[英]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
這很簡單。
在第一代碼中,“協議”這是商定reader
和writer
是writer
將數據發送到任意數量的reader
,然后writer
發送“DONE”, reader
接收它后,就知道數據傳輸完成。
在您的第二個代碼中, reader
和writer
之間沒有達成一致的協議 ,因為作家的觀點是“ 我發送了兩個對象,我就完成了! ”,而讀者的觀點是“ *我收到了三個對象,而我完成了!”。
由於運行時環境的任何部分都無法檢測到協議錯誤,因此應用程序只是阻塞,等待永遠不會出現的數據。 可以檢測到這種情況的唯一一個是應用程序本身,因為它是唯一知道它遵循的協議的應用程序。 為此,可以使用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.