簡體   English   中英

多重處理的queue.get()何時返回DONE?

[英]When does multiprocessing's queue.get() return DONE?

我正在學習Python多處理模塊,並且找到了以下示例:

from multiprocessing import Process, Queue
import time

def reader(queue):
    ## Read from the queue
    while True:
        msg = queue.get()         # Read from the queue and do nothing
        if (msg == 'DONE'):
            break

def writer(count, queue):
    ## Write to the queue
    for ii in xrange(0, count):
        queue.put(ii)             # Write 'count' numbers into the queue
    queue.put('DONE')

if __name__=='__main__':
    for count in [10**4, 10**5, 10**6]:
        queue = Queue()   # reader() reads from queue
                          # writer() writes to queue
        reader_p = Process(target=reader, args=((queue),))
        reader_p.daemon = True
        reader_p.start()        # Launch reader() as a separate python process

        _start = time.time()
        writer(count, queue)    # Send a lot of stuff to reader()
        reader_p.join()         # Wait for the reader to finish
        print "Sending %s numbers to Queue() took %s seconds" % (count, 
            (time.time() - _start))

我想知道queue.get()何時返回DONE所以我嘗試了以下示例:

#!/bin/env python
from multiprocessing import Process, Queue
import time

if __name__=='__main__':
  queue = Queue()

  print "Before 2x put"
  queue.put(10)
  queue.put(20)
  print "After 2x put"

  print "Before 1s get"
  print queue.get()
  print "After 1st get"

  print "Before 2nd get"
  print queue.get()
  print "After 2nd get"

  print "Before 3rd get"
  print queue.get()
  print "After 3rd get"

該腳本的最后一條消息是Before 3rd get ,此后該腳本卡住了,結束腳本的唯一方法是終止它。 從此示例中,您可以看到queue.get()正在阻塞(直到結束,代碼才繼續)。 發生這種情況時,原始代碼中的queue.get()返回DONE

編輯

回復@KemyLand很好地解釋了這里發生的事情,這是沒有被卡住的版本:

#!/bin/env python
from multiprocessing import Process, Queue
import time

if __name__=='__main__':
  queue = Queue()

  print "Before 2x put"
  queue.put(10)
  queue.put(20)
  print "After 2x put"

  print "Before 1s get"
  print queue.get()
  print "After 1st get"

  print "Before 2nd get"
  print queue.get()
  print "After 2nd get"

  print "Before 3rd get"
  try:
    print queue.get_nowait()
    print "After 3rd get"
  except:
    pass

這很簡單。

在第一代碼中,“協議”這是商定readerwriterwriter將數據發送到任意數量的reader ,然后writer發送“DONE”, reader接收它后,就知道數據傳輸完成。

在您的第二個代碼中, readerwriter之間沒有達成一致的協議 ,因為作家的觀點是“ 我發送了兩個對象,我就完成了! ”,而讀者的觀點是“ *我收到了三個對象,而我完成了!”。

由於運行時環境的任何部分都無法檢測到協議錯誤,因此應用程序只是阻塞,等待永遠不會出現的數據。 可以檢測到這種情況的唯一一個是應用程序本身,因為它是唯一知道它遵循的協議的應用程序。 為此,可以使用Queue.Queue.get_nowait()必須 import Queue (使用大寫Queue.Queue Q表示 ,因為multiprocessing.Queue只是Queue.Queue的別名))。 如果UCH功能不能從inmediatedly提取目標Queue ,它會拋出一個Queue.Empty例外。 (注意:與模塊名稱的混淆在Python 3中已修復)。

暫無
暫無

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

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