在队列中join()与task_done()的关联性

1.基础解释:
Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
Queue.join() 实际上意味着等到队列为空,再执行别的操作

如果线程里每从队列里取一次,但没有执行task_done(),则join无法判断队列到底有没有结束,在最后执行个join()是等不到结果的,会一直挂起。
可以理解为,每task_done一次 就从队列里删掉一个元素,这样在最后join的时候根据队列长度是否为零来判断队列是否结束,从而执行主线程。
-----无限挂起的样例:

import time
import random
from multiprocessing import JoinableQueue,Process

def consumer(jq,name):
    while True:
        food = jq.get()
        time.sleep(random.uniform(1,2))
        print('%s吃完%s'%(name,food))
        # jq.task_done()

def producer(jq):
    for i in range(1,10):
        time.sleep(random.random())
        food = '甜品%s'%i
        print('%s生产了%s'%('满记甜品店',food))
        jq.put(food)
    jq.join()


if __name__ == '__main__':
    jq = JoinableQueue(5)
    c1 = Process(target=consumer,args=(jq,'doony'))
    p1 = Process(target=producer,args=(jq,))
    c1.daemon = True
    c1.start()
    p1.start()
    p1.join()

  运行结果:

--------task_done():

import time
import random
from multiprocessing import JoinableQueue,Process

def consumer(jq,name):
    while True:
        food = jq.get()
        time.sleep(random.uniform(1,2))
        print('%s吃完%s'%(name,food))
        jq.task_done()

def producer(jq):
    for i in range(1,10):
        time.sleep(random.random())
        food = '甜品%s'%i
        print('%s生产了%s'%('满记甜品店',food))
        jq.put(food)
    jq.join()


if __name__ == '__main__':
    jq = JoinableQueue(5)
    c1 = Process(target=consumer,args=(jq,'doony'))
    p1 = Process(target=producer,args=(jq,))
    c1.daemon = True
    c1.start()
    p1.start()
    p1.join()

  运行结果:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2019-04-20 13:58  醉醺醺的  阅读(281)  评论(0编辑  收藏  举报