多处理的queue.get()何时返回DONE?

时间:2015-08-24 21:56:37

标签: python multithreading multiprocessing python-multiprocessing

我正在学习Python多处理模块,我发现this示例:

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

0 个答案:

没有答案