03生产者消费者模型
from multiprocessing import Process, Queue, JoinableQueue import time, random, os def producer(q): for i in range(10): time.sleep(random.randint(1,3)) res = '包子{}'.format(i) q.put(res) print('{}生产了{}'.format(os.getpid(), res)) def consumer(q): while True: res = q.get() time.sleep(random.randint(1,3)) print('{}吃了{}'.format(os.getpid(), res)) if __name__ == '__main__': q = Queue() # 生产者 p1 = Process(target=producer, args=(q,)) # 消费者 c1 = Process(target=consumer, args=(q,)) p1.start() c1.start() print('主')
上面程序的问题是不能正常结束,消费者不能结束,下面是改动后
def producer(q): for i in range(3): time.sleep(random.randint(1,3)) res = '包子{}'.format(i) q.put(res) print('{}生产了{}'.format(os.getpid(), res)) def consumer(q): while True: res = q.get() if res is None:break time.sleep(random.randint(1,3)) print('{}吃了{}'.format(os.getpid(), res)) if __name__ == '__main__': q = Queue() # 生产者 p1 = Process(target=producer, args=(q,)) # 消费者 c1 = Process(target=consumer, args=(q,)) p1.start() c1.start() p1.join() q.put(None) print('主')
如果有多个生产者、消费者,那么做如下改动,这个做法很不好,以后用JoinableQueue
def producer(q): for i in range(3): time.sleep(random.randint(1,3)) res = '包子{}'.format(i) q.put(res) print('{}生产了{}'.format(os.getpid(), res)) def consumer(q): while True: res = q.get() if res is None:break time.sleep(random.randint(1,3)) print('{}吃了{}'.format(os.getpid(), res)) if __name__ == '__main__': q = Queue() # 生产者 p1 = Process(target=producer, args=(q,)) p2 = Process(target=producer, args=(q,)) # 消费者 c1 = Process(target=consumer, args=(q,)) c2 = Process(target=consumer, args=(q,)) c3 = Process(target=consumer, args=(q,)) p1.start() p2.start() c1.start() c2.start() c3.start() p1.join() p2.join() q.put(None)#有几个消费者就要传递几个信号 q.put(None) q.put(None) print('主')
用JoinableQueue与守护进程应用来解决问题
JoinableQueue([maxsize]):这就像是一个Queue对象,但队列允许项目的使用者通知生成者项目已经被成功处理。
通知进程是使用共享的信号和条件变量来实现的。
#参数介绍:
maxsize是队列中允许最大项数,省略则无大小限制。
方法介绍:
JoinableQueue的实例p除了与Queue对象相同的方法之外还具有:
q.task_done():使用者使用此方法发出信号,表示q.get()的返回项目已经被处理。如果调用此方法的次数大于从队列中删除项目的数量,将引发ValueError异常
q.join():生产者调用此方法进行阻塞,直到队列中所有的项目均被处理。阻塞将持续到队列中的每个项目均调用q.task_done()方法为止
def producer(q): for i in range(3): time.sleep(random.randint(1,3)) res = '包子{}'.format(i) q.put(res) print('{}生产了{}'.format(os.getpid(), res)) def consumer(q): while True: res = q.get() if res is None:break time.sleep(random.randint(1,3)) print('{}吃了{}'.format(os.getpid(), res)) q.task_done() if __name__ == '__main__': q = JoinableQueue() # 生产者 p1 = Process(target=producer, args=(q,)) p2 = Process(target=producer, args=(q,)) # 消费者 c1 = Process(target=consumer, args=(q,)) c2 = Process(target=consumer, args=(q,)) c3 = Process(target=consumer, args=(q,)) c1.daemon = True#设置为守护进程 c2.daemon = True#设置为守护进程 c3.daemon = True#设置为守护进程 p1.start() p2.start() c1.start() c2.start() c3.start() p1.join() p2.join() q.join()#保证队列为空 print('主')##消费者已设置为守护进程,主进程结束后,子进程也会随之结束
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】