# -*- coding: UTF-8 -*-"""多线程同时读队列使用 join(), task_done()逻辑:3个子线程并发 从有6个数据的队列中取数据,并且打印出来。主线程等待队列空了才结束总结:1、主线程 调用 q.join()等待队列为空时,应该不是根据 q.qsize()判断的也就是在Queue设计上,q.qsize()操作的内部队列大小变量 和 task_done()操作的内部队列大小变量不是同一个使用:1、正常创建队列,往队列中读写数据2、在线程处理完一个队列数据后加上 q.task_done()3、在主线程中执行 q.join()资料:Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号Queue.join() 实际上意味着等到队列为空,再执行别的操作如果线程里每从队列里取一次,但没有执行task_done(),则join无法判断队列到底有没有结束,在最后执行个join()是等不到结果的,会一直挂起。可以理解为,每task_done一次 就从队列里删掉一个元素,这样在最后join的时候根据队列长度是否为零来判断队列是否结束,从而执行主线程。"""import Queueimport threadingimport timeimport randomq = Queue.Queue(0) # 无限大小的队列NUM_WORKERS = 3 # 线程数量class MyThread(threading.Thread):"""从队列读取数据打印"""def __init__(self,queue,threadid):""":param queue:队列:param threadid: 线程编号"""threading.Thread.__init__(self)self._jobq = queueself._threadid = threadiddef run(self):## 每个子线程不断从队列中读取数据,知道队列空才结束while True:time.sleep( random.random()*5)# 获取队列数据data = Nonetry:data = self._jobq.get(False) # 队列空,抛出异常except:break## 效果同上# if self._jobq.qsize()>0:#data = self._jobq.get()# else:#breakprint "doing", data, " sub_process ", self._threadidself._jobq.task_done() # 执行发送信号 告诉执行join()等待的线程,队列中又少了一个数据啦print "sub_process end:",self._threadidif __name__ == '__main__':print "begin...."# 往队列写数据for i in range(NUM_WORKERS * 2):q.put(i)print "job qsize:",q.qsize()# 启动线程for x in range(NUM_WORKERS):MyThread(q,x).start()q.join() # 主线程等待队列空,子线程执行一次task_done(),它就知道队列大小减一了print "end""""Out:begin....job qsize: 6doing 0 sub_process 1doing 1 sub_process 0doing 2 sub_process 1doing 3 sub_process 2doing 4 sub_process 2doing 5 sub_process 0endsub_process end: 1sub_process end: 2sub_process end: 0"""
如果觉得《python 归纳 (十八)_队列Queue在多线程中使用(二)》对你有帮助,请点赞、收藏,并留下你的观点哦!