欢迎使用 小书匠(xiaoshujiang)编辑器,您能够经过 小书匠主按钮>模板
里的模板管理来改变新建文章的内容。html
joinablequeue实现生产者消费者模型程序员
一、使用Queue实现的代码编程
import time import random from multiprocessing import Process,Queue def producer(q,name,food): for i in range(2): time.sleep(random.random()) fd = '%s%s'%(food,i) q.put(fd) print('%s生产了一个%s'%(name,food)) def consumer(q,name): while True: food = q.get() if not food:break time.sleep(random.randint(1,3)) print('%s吃了%s'%(name,food)) def cp(c_count,p_count): q = Queue(10) for i in range(c_count): Process(target=consumer, args=(q, '灰太狼')).start() p_l = [] for i in range(p_count): p1 = Process(target=producer, args=(q, '喜洋洋', '包子')) p1.start() p_l.append(p1) for p in p_l:p.join() for i in range(c_count): q.put(None) if __name__ == '__main__': cp(2,3) ----------------结果: 喜洋洋生产了一个包子 喜洋洋生产了一个包子 喜洋洋生产了一个包子 喜洋洋生产了一个包子 喜洋洋生产了一个包子 喜洋洋生产了一个包子 灰太狼吃了包子1 灰太狼吃了包子0 灰太狼吃了包子0 灰太狼吃了包子0 灰太狼吃了包子1 灰太狼吃了包子1
二、使用joinablequeue实现队列
(1)消费者不须要判断从队列里拿到None再退出执行消费者函数了
(2)消费者每次从队列里面q.get()一个数据,处理事后就使用队列.task_done()
(3)生产者for循环生产完全部产品,须要q.join()阻塞一下,对这个队列进行阻塞。
(4)启动一个生产者,启动一个消费者,而且这个消费者作成守护进程,而后生产者须要p.join()阻塞一下。
(5)我启动了生产者以后,生产者函数一直在生成数据,直到生产完全部数据将队列q.join()一下,意思是当我生产的数据都被消费者消费完以后 队列的阻塞才结束。
(6)结束过程:消费者这边是每消费完一个数据给队列返回一个q.task_done(),直到全部的数据都被消费完以后,生产者函数这边的队列.阻塞结束了,队列阻塞结束了生产者函数执行结束了。生产者函数结束了,那么p.join()生产者进程对象就结束了。生产者进程对象结束了整个主进程的代码就执行结束了。主进程代码结束了守护进程及消费者进程也结束了app
import time import random from multiprocessing import JoinableQueue,Process def producer(q,name,food): for i in range(5): time.sleep(random.random()) fd = '%s%s'%(food,i+1) q.put(fd) print('%s生产了一个%s'%(name,food)) q.join()#(3)生产者for循环生产完全部产品,须要q.join()阻塞一下,对这个队列进行阻塞。 #(5)我启动了生产者以后,生产者函数一直在生成数据,直到生产完全部数据将队列q.join()一下,意思是当我生产的数据都被消费者消费完以后 队列的阻塞才结束。 def consumer(q,name): #(1)消费者不须要像Queue那样判断从队列里拿到None再退出执行消费者函数了 while True: food = q.get() time.sleep(random.random()) print('%s吃了%s'%(name,food)) q.task_done() #(2)消费者每次从队列里面q.get()一个数据,处理事后就使用队列.task_done() if __name__ == '__main__': jq = JoinableQueue() p =Process(target=producer,args=(jq,'喜洋洋','包子')) # p.start() #(4)启动一个生产者,启动一个消费者,而且这个消费者作成守护进程,而后生产者须要p.join()阻塞一下。 c = Process(target=consumer,args=(jq,'灰太狼')) c.daemon = True # c.start() p.join() #(6)结束过程:消费者这边是每消费完一个数据给队列返回一个q.task_done(),直到全部的数据都被消费完以后,生产者函数这边的队列.阻塞结束了,队列阻塞结束了生产者函数执行结束了。生产者函数结束了,那么p.join()生产者进程对象就结束了。生产者进程对象结束了整个主进程的代码就执行结束了。主进程代码结束了守护进程即消费者进程也结束了 ---------------结果: 喜洋洋生产了一个包子 灰太狼吃了包子1 喜洋洋生产了一个包子 喜洋洋生产了一个包子 喜洋洋生产了一个包子 喜洋洋生产了一个包子 灰太狼吃了包子2 灰太狼吃了包子3 灰太狼吃了包子4 灰太狼吃了包子5 import time import random from multiprocessing import JoinableQueue,Process def producer(q,name,food): for i in range(5): time.sleep(random.random()) fd = '%s%s'%(food,i+1) q.put(fd) print('%s生产了一个%s'%(name,food)) q.join() def consumer(q,name): while True: food = q.get() time.sleep(random.random()) print('%s吃了%s'%(name,food)) q.task_done() if __name__ == '__main__': jq = JoinableQueue() p =Process(target=producer,args=(jq,'喜洋洋','包子')) p.start() c = Process(target=consumer,args=(jq,'灰太狼')) c.daemon = True c.start() p.join()
三、两者区别
1)Queue有多少消费者,就要put多少个None。要在消费者函数添加if 不是真(非None数据)就退出死循环
2)两者效果同样可是从程序员角度看,joinablequeue更加严谨,更符合编程思惟dom