繁体   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