[b0033] python 归纳 (十八)_队列Queue在多线程中使用(二)
# -*- 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 Queue import threading import time import random q = 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 = queue self._threadid = threadid def run(self): ## 每个子线程不断从队列中读取数据,知道队列空才结束 while True: time.sleep( random.random()*5) # 获取队列数据 data = None try: data = self._jobq.get(False) # 队列空,抛出异常 except: break ## 效果同上 # if self._jobq.qsize()>0: # data = self._jobq.get() # else: # break print "doing", data, " sub_process ", self._threadid self._jobq.task_done() # 执行发送信号 告诉执行join()等待的线程,队列中又少了一个数据啦 print "sub_process end:",self._threadid if __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: 6 doing 0 sub_process 1 doing 1 sub_process 0 doing 2 sub_process 1 doing 3 sub_process 2 doing 4 sub_process 2 doing 5 sub_process 0 end sub_process end: 1 sub_process end: 2 sub_process end: 0 """
写满200篇博文再说