Python - Asyncio异步模块实现的生产消费者模型

本文介绍了如何使用Python的asyncio库通过生产者消费者模型模拟面包制作过程,展示了多线程和队列在协程中的应用,以及如何协调生产与消费的速度差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在设计模式中,生产消费者模型占有非常重要的地位,这个模型在现实世界中也有很多有意思的对应场景,比如做包子的人和吃包子的人,当两者速度不匹配时,就需要有一个模型来做匹配(偶合),实现做的包子都会依次消费掉。

如下代码:

import asyncio
 
 
class ConsumerProducerModel:
    def __init__(self, producer, consumer, queue=asyncio.Queue(), plate_size=6):  # the plate holds 6pcs bread
        self.queue = queue
        self.producer = producer
        self.consumer = consumer
        self.plate_size = plate_size
 
    async def produce_bread(self):
        for i in range(self.plate_size):
            bread = f"bread {i}"
            await asyncio.sleep(0.5)  # bread makes faster, 0.5s/pc
            await self.queue.put(bread)
            print(f'{self.producer} makes {bread}')
 
    async def consume_bread(self):
        while True:
            bread = await self.queue.get()
            await asyncio.sleep(1)  # eat slower, 1s/pc
            print(f'{self.consumer} eats {bread}')
            self.queue.task_done()
 
 
async def main():
    queue = asyncio.Queue()
    cp1 = ConsumerProducerModel("John", "Grace", queue)  # group 1
    cp2 = ConsumerProducerModel("Mike", "Lucy", queue)  # group 2
 
    producer_1 = cp1.produce_bread()
    producer_2 = cp2.produce_bread()
 
    consumer_1 = asyncio.ensure_future(cp1.consume_bread())
    consumer_2 = asyncio.ensure_future(cp2.consume_bread())
 
    await asyncio.gather(*[producer_1, producer_2])
    await queue.join()
    consumer_1.cancel()
    consumer_2.cancel()
 
 
if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()

后记

生产消费者模型可以使用多线程和队列来实现,这里选择协程不仅是因为性能不错,而且整个下来逻辑清晰:

  1. 先定义初始化的东西,要有个队列,要有生产者,要有消费者,要有装面包的盘子大小;

  2. 生产者:根据盘子大小生产出对应的东西(面包),将东西放入盘子(queue);

  3. 消费者:从盘子上取东西,每次取东西都是一个任务,每次任务完成,就标记为task_done(调用函数)。在这个层面,一直循环;

  4. 主逻辑:实例化生产消费者模型对象,创建生产者协程,创建任务(ensure_future),收集协程结果,等待所有线程结束(join),手动取消两个消费者协程;

  5. 运行:首先创建事件循环,然后进入主逻辑,直到完成,关闭循环。

以上,欢迎交流!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值