一、什么是生产者消费者模型
生产者消费者模型就是通过一个容器解决它们之间的强耦合问题,生产者与消费者之间依靠阻塞队列进行通讯,生产者与消费者之间不直接通讯,这样平衡了二者之间的处理能力,这里使用了进程、线程以及生成器实现了生产者消费者模型。
在进程中分别开启了生产者和消费者的进程,它们之间的通讯依赖进程中的队列Queue来实现的。在线程中分别开启了生产者和消费者线程,它们之间的通讯依赖queue中的Queue完成通讯。协程的使用生成器简单的实现。
使用进程的方式会耗费大量cpu的资源(包括进程的创建、切换、销毁);线程的方式相比进程来讲切换会较少损耗cpu的资源;协程的方式理论上来讲cpu的利用率达到100%,所以协程应该是较为理想的选择。
二、使用进程实现生产者消费者模型
from multiprocessing import Process from multiprocessing import Queue def producer(q, name): # 生产者生产20个数据 for i in range(20): q.put(str(i)) print("%s生产第%s个" % (name, i)) def consumer(q, name): while True: # 从队列中获取数据 data = q.get() if data: print("%s消费第%s个" % (name, data)) else: break if __name__ == '__main__': q = Queue() # 创建10个生产者 p_pro_list = [] for i in range(10): p_pro = Process(target=producer, args=(q, "生产者%s" % i)) p_pro_list.append(p_pro) p_pro.start() # 等待所有的生产进程结束 for j in p_pro_list: j.join() # 然后再q中加入结束标示,用于消费者判断队列中是否还有数据,有多少个生产者加入多少个None for k in p_pro_list: q.put(None) # 创建5个消费者 p_con_list = [] for i in range(5): p_con = Process(target=consumer, args=(q, "消费者%s" % i)) p_con_list.append(p_con) p_con.start() for j in p_con_list: j.join()
三、使用线程实现生产者消费者模型
import threading from queue import Queue def producer(q, name): for item in range(20): q.put(item) print("%s-%s" % (name, item)) def consumer(q, name): while True: item = q.get() if item is None: break print("%s-%s" % (name, item)) q.task_done() # 任务完成后向队列发送一个讯号通知一下 if __name__ == '__main__': q = Queue() # 等待消费者消费q中的产品,与task_done搭配使用 q.join() # 生产者生产产品 t_pro = threading.Thread(target=producer, args=(q, '生产者生产')) t_pro.start() # 消费者消费产品 t_con = threading.Thread(target=consumer, args=(q, '消费者消费')) t_con.start()
四、使用线程实现生产者消费者模型
协程的运行是由程序员控制而非操作系统,所以可以通过yield进行简单的实现。
import time import random def consumer(): while True: item = yield print("消费%s" % item) def producer(): # 第一次调用生成器时,使用next()语句或是send(None),不能使用send发送一个非None的值,否则会出错的。 c.send(None) # 相当于c.next()激活生成器 while True: time.sleep(1) item = random.randint(1, 50) print("生产%s" % item) # 进入生成器函数,此时将item赋值给yield并且传回。相当于把item赋值给consumer中的item。 c.send(item) if __name__ == '__main__': # 消费者生成器 c = consumer() producer()