1
Python應用程序我正在開發一個文件夾的監視器並將某些新的或更改的文件上載到服務器。作爲一個任務隊列,我使用了Queue模塊和一個工作線程池。取消線程中的任務執行並從隊列中刪除任務
有時在上傳過程中文件發生變化,上傳需要被取消並全部開始。
我知道如何使用threading.Event來停止線程執行,但是如何移除或移動Queue中的任務?
Python應用程序我正在開發一個文件夾的監視器並將某些新的或更改的文件上載到服務器。作爲一個任務隊列,我使用了Queue模塊和一個工作線程池。取消線程中的任務執行並從隊列中刪除任務
有時在上傳過程中文件發生變化,上傳需要被取消並全部開始。
我知道如何使用threading.Event來停止線程執行,但是如何移除或移動Queue中的任務?
這樣做將標誌着你已經裝載到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
/appendleft
和pop
/popleft
以外的操作在deque
上的執行效果不如在list
實例上的效果;甚至像__getitem__
那樣簡單的東西是O(n)
。
哇,我不知道是否可以更改已發送到隊列的數據從發件人線程。它是線程安全的嗎? – Warwick 2014-11-07 01:43:11
@Warwick,只要你從發送者線程設置一個屬性,並從消費者那裏讀取該屬性,是的。設置和讀取屬性在CPython中都是原子的,而且由於GIL,兩種操作都不能並行運行。一個將始終在另一個之前開始並完成。 – dano 2014-11-07 02:05:32