2014-11-06 139 views
1

Python应用程序我正在开发一个文件夹的监视器并将某些新的或更改的文件上载到服务器。作为一个任务队列,我使用了Queue模块和一个工作线程池。取消线程中的任务执行并从队列中删除任务

有时在上传过程中文件发生变化,上传需要被取消并全部开始。

我知道如何使用threading.Event来停止线程执行,但是如何移除或移动Queue中的任务?

回答

1

这样做将标志着你已经装载到Queue作为取消实例的最简单的方法:在你的消费线程

class Task(object): 
    def __init__(self, data): 
     self.cancelled = False 
     self.data = data 

    def cancel(self): 
     self.cancelled = True 

q = Queue.Queue() 
t = Task("some data to put in the queue") 
q.put(t) 

# Later 
t.cancel() 

然后:

task = q.get() 
if task.cancelled: 
    # Skip it 
else: 
    # handle it. 

也可以与直接交互Queue在内部使用,前提是您获取用于同步访问Queue的内部互斥锁:

>>> import Queue 
>>> q = Queue.Queue() 
>>> q.put("a") 
>>> q.put("b") 
>>> q.put("c") 
>>> q.put("d") 
>>> q.queue[2] 
'c' 
>>> q.queue[3] 
'd' 
>>> with q.mutex: # Always acquire the lock first in actual usage 
... q.queue[3] 
... 
'd' 

虽然这应该工作,不建议用Queue的内部搞乱,并且可以跨Python版本打破如果Queue变更的实现。此外,请记住append/appendleftpop/popleft以外的操作在deque上的执行效果不如在list实例上的效果;甚至像__getitem__那样简单的东西是O(n)

+0

哇,我不知道是否可以更改已发送到队列的数据从发件人线程。它是线程安全的吗? – Warwick 2014-11-07 01:43:11

+0

@Warwick,只要你从发送者线程设置一个属性,并从消费者那里读取该属性,是的。设置和读取属性在CPython中都是原子的,而且由于GIL,两种操作都不能并行运行。一个将始终在另一个之前开始并完成。 – dano 2014-11-07 02:05:32