簡體   English   中英

在python的多處理中檢查空隊列

[英]Checking for empty Queue in python's multiprocessing

我有一個使用 python 的包 multiprocessing 和 Queue 的程序。 我的功能之一具有以下結構:

from multiprocessing import Process, Queue
def foo(queue):
   while True:
       try:
           a = queue.get(block = False)
           doAndPrintStuff(a)
       except:
           print "the end"
           break

   if __name__ == "__main__"
     nthreads = 4
     queue = Queue.Queue()
     # put stuff in the queue here 
     for stuff in moreStuff:
         queue.put(stuff)
     procs = [Process(target = foo, args = (queue,)) for i in xrange(nthreads)]
     for p in procs:
       p.start()
     for p in procs:
       p.join()

這個想法是,當我嘗試從隊列中提取並且它為空時,它會引發異常並終止循環。 所以我有兩個問題:

1)這是一個安全的習語嗎? 有沒有更好的方法來做到這一點?

2)我試圖找出當我嘗試從空隊列中.get()時引發的確切異常是什么。 目前我的程序正在捕獲所有異常,當錯誤發生在其他地方時這很糟糕,我只收到“結束”消息。

我試過:

  import Queue
  queue = Queue.Queue()
  [queue.put(x) for x in xrange(10)]
  try: 
       print queue.get(block = False)
  except Queue.Empty:
       print "end"
       break

但我收到了錯誤,就好像我沒有發現異常一樣。 捕獲的正確異常是什么?

例外應該是Queue.Empty 但你確定你得到了同樣的錯誤嗎? 在第二個示例中,您還將隊列本身從multiprocessing.Queue切換到Queue.Queue ,我認為這可能是問題所在。

這可能看起來很奇怪,但您必須使用multiprocessing.Queue類,但使用Queue.Empty異常(您必須自己從Queue模塊導入)

在刷新put緩沖區之前,Queue似乎是空的,這可能需要一段時間。

我們的問題的解決方案是使用 哨兵 ,也許內置task_done()調用:

task_done()

表示以前排隊的任務已完成。 由隊列使用者線程使用。 對於用於獲取任務的每個get(),對task_done()的后續調用會告知隊列該任務的處理已完成。

如果join()當前正在阻塞,則它將在所有項目都已處理后恢復(這意味着已為每個已放入隊列的項目收到task_done()調用)。

如果調用的次數超過隊列中放置的項目,則引發ValueError。

這是一個示例 - 正如@Steven 上面所說,您需要使用標准隊列中的 queue.Empty 異常。 文檔中的注釋( https://docs.python.org/3/library/multiprocessing.html ):

筆記

multiprocessing 使用通常的 queue.Empty 和 queue.Full 異常來表示超時。 它們在多處理命名空間中不可用,因此您需要從隊列中導入它們。

基本示例:

 from multiprocessing import Process, Queue, Manager
 import queue

def firstPass(q):
    driver = getDriver()

    while True:
        try:      
            link = q.get_nowait()   
            f(driver, link)
        except queue.Empty:
            logger.info("empty queue")
            driver.close()
            break

嘗試閱讀隊列庫文檔。 你不是在尋找Queue.empty()嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM