1 """ 2 线程通信的生产者与消费者 3 python的queue模块中提供了同步的线程安全的队列类,都具有原子性,实现线程间的同步 4 Queue (FIFO: fist in fist out) 5 LifoQueue (LIFO: last in fist out) 6 PriorityQueue (优先级队列) 7 8 task_done(): 9 作用是在使用join()的时候,当queue中所有的项目都被取出,且每个项目取出后都使用了task_done(),那么就可以释放join()阻塞 10 系统解释如下: 11 用于消费者,每次get()以后,使用task_done() 是告诉队列正在处理的get任务完成 12 如果join()当前处于阻塞状态,那么当处理完所有项时它将继续运行(这意味着对于已经放入队列的每个项都接收到task_done()调用)。 13 如果调用的次数超过在队列中放置的项的次数,则引发ValueError错误。 14 15 如果不需要join()的时候也可以不使用task_done() 16 17 18 """ 19 import queue 20 import threading 21 import time 22 import random 23 24 q = queue.Queue(10) 25 26 27 def produce(): 28 i = 0 29 while i < 10: 30 num = random.randint(1, 100) 31 q.put("生产者生产出数据:%d" % num) 32 print("生产者生产出数据:%d" % num) 33 time.sleep(0.2) 34 i += 1 35 print("生产结束") 36 37 38 def consume(): 39 while True: 40 time.sleep(0.3) 41 if q.empty(): 42 break 43 item = q.get() 44 print("消费者取出:", item) 45 q.task_done() 46 47 print("消费者结束") 48 49 50 if __name__ == '__main__': 51 52 # 创建生产者 53 t1 = threading.Thread(target=produce, name="生产者") 54 t1.start() 55 time.sleep(0.1) 56 57 # 创建消费者 58 t2 = threading.Thread(target=consume, name="消费者") 59 t2.start() 60 q.join() 61 62 print("over") 63 64 65 # from threading import Thread 66 # import time 67 # import random 68 # from queue import Queue 69 # from collections import deque 70 # from datetime import datetime 71 # 72 # # 创建队列,设置队列最大数限制为3个 73 # queue = Queue(3) 74 # 75 # 76 # # 生产者线程 77 # class Pro_Thread(Thread): 78 # def run(self): 79 # # 原材料准备,等待被生产,这里使用的是双向队列 80 # tasks = deque([1, 2, 3, 4, 5, 6, 7, 8]) 81 # global queue 82 # while True: 83 # try: 84 # # 从原材料左边开始生产,如果tasks中没有元素,调用popleft()则会抛出错误 85 # task = tasks.popleft() 86 # queue.put(task) 87 # print(datetime.now(), "生产", task, "现在队列数:", queue.qsize()) 88 # 89 # # 休眠随机时间 90 # time.sleep(0.5) 91 # # 如果原材料被生产完,生产线程跳出循环 92 # except IndexError: 93 # print("原材料已被生产完毕") 94 # break 95 # print("生产完毕") 96 # 97 # 98 # # 消费者线程 99 # class Con_Thread(Thread): 100 # def run(self): 101 # global queue 102 # while True: 103 # if not queue.empty(): 104 # # 通过get(),这里已经将队列减去了1 105 # task = queue.get() 106 # time.sleep(2) 107 # # 发出完成的信号,不发的话,join会永远阻塞,程序不会停止 108 # queue.task_done() 109 # print(datetime.now(), "消费", task) 110 # else: 111 # break 112 # print("消费完毕") 113 # 114 # 115 # # r入口方法,主线程 116 # def main(): 117 # Pro_1 = Pro_Thread() 118 # # 启动线程 119 # Pro_1.start() 120 # # 这里休眠一秒钟,等到队列有值,否则队列创建时是空的,主线程直接就结束了,实验失败,造成误导 121 # time.sleep(1) 122 # for i in range(2): 123 # Con_i = Con_Thread() 124 # # 启动线程 125 # Con_i.start() 126 # global queue 127 # # 接收信号,主线程在这里等待队列被处理完毕后再做下一步 128 # queue.join() 129 # # 给个标示,表示主线程已经结束 130 # print("主线程结束") 131 # 132 # 133 # if __name__ == '__main__': 134 # main()