我有一些線程在等待某個事件,執行一些操作,然後再次等待該事件。另一個線程會在適當時觸發事件。Python threading.Event() - 確保所有等待的線程在event.set()上醒來
我找不出一種方法來確保每個等待的線程在設置事件時只觸發一次。我目前有觸發線程設置它,睡一會兒,然後清除它。不幸的是,這會導致等待的線程多次抓取設置的事件,或者根本沒有。
我不能簡單地讓觸發線程產生響應線程來運行它們一次,因爲它們是對來自其他地方的請求的響應。
簡而言之:在Python中,如何讓一個線程設置一個事件,並確保每個等待線程在事件清除之前只對其執行一次事件?
更新:
我已經嘗試設置它使用鎖和一個隊列,但它不工作。下面是我有:
# Globals - used to synch threads
waitingOnEvent = Queue.Queue
MainEvent = threading.Event()
MainEvent.clear() # Not sure this is necessary, but figured I'd be safe
mainLock = threading.Lock()
def waitCall():
mainLock.acquire()
waitingOnEvent.put("waiting")
mainLock.release()
MainEvent.wait()
waitingOnEvent.get(False)
waitingOnEvent.task_done()
#do stuff
return
def triggerCall():
mainLock.acquire()
itemsinq = waitingOnEvent.qsize()
MainEvent.set()
waitingOnEvent.join()
MainEvent.clear()
mainLock.release()
return
第一次,itemsinq正確反映了許多呼叫的方式等待,但只有前等待的線程進行調用將使它通過。從那時起,itemsinq總是1,等待的線程輪流;每次發生觸發呼叫時,下一次都會經過。
更新2 看來好像只有event.wait()的一個線程被喚醒
,然而在queue.join()工作。這向我建議,一個等待線程喚醒,從隊列中抓取並調用task_done(),並且單個get()/ task_done()以某種方式清空隊列並允許join()。觸發線程然後完成join(),清除事件,從而阻止其他等待線程通過。但是,爲什麼只有一次get/task_done調用後,隊列纔會被註冊爲空/完成?
即使我註釋掉queue.get()和queue.task_done()並掛起觸發器,以至於無法清除事件,似乎只有一個人正在醒來。
這聽起來像是一個可能的設計缺陷,可能有更好的方法去實現你想要完成的任務。你能發佈關於線程應該做什麼的更多細節嗎? – 2010-08-04 21:36:29