Asyncio Queue

本文探讨了异步编程在Python中的实现,通过使用asyncio库创建了一个简单的生产者-消费者模型,展示了如何利用事件循环进行高效的任务调度。在jupyter环境中,特别介绍了nest_asyncio的使用,以解决事件循环的兼容性问题。

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

新的启动事件循环

import asyncio
import random
import time
import logging
from contextlib import closing

import nest_asyncio

nest_asyncio.apply( )  # 在jupyter需要这个,不然asyncio运行出错
logging.basicConfig(  # 用日志打印输出信息
    level = logging.INFO,
    format = "%(asctime)s %(process)d %(thread)d [*] %(message)s"
)


async def newsProducer(myQueue):
    while True:
        await asyncio.sleep(1)
        data = random.randint(1, 5)
        logging.info(f"将产品放入队列{data}")
        await myQueue.put(data)


async def newsConsumer(id, myQueue):
    while True:
        logging.info("消费者: {} 试图从队列中获取".format(id))
        item = await myQueue.get( )
        if item is None:
            break
        logging.info("消费者: {} 消耗了ID的商品: {}".format(id, item))


async def main( ):
    myQueue = asyncio.Queue(maxsize = 10)
    await asyncio.gather(
        newsProducer(myQueue),
        newsConsumer("A", myQueue),
        newsConsumer("B", myQueue),
    )


if __name__ == "__main__":
    # 修改了这里
    with closing(asyncio.get_event_loop( )) as loop:
        loop.run_until_complete(main( ))

旧的启动事件循环

import asyncio
import random
import time
import logging
import nest_asyncio
nest_asyncio.apply() # 在jupyter需要这个,不然asyncio运行出错
logging.basicConfig(  # 用日志打印输出信息
    level=logging.INFO,
    format="%(asctime)s %(process)d %(thread)d [*] %(message)s"
)


async def newsProducer(myQueue):
    while True:
        await asyncio.sleep(1)
        data = random.randint(1, 5)
        logging.info(f"将产品放入队列{data}")
        await myQueue.put(data)


async def newsConsumer(id, myQueue):
    while True:
        logging.info("消费者: {} 试图从队列中获取".format(id))
        item = await myQueue.get()
        if item is None:
            break
        logging.info("消费者: {} 消耗了ID的商品: {}".format(id, item))

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    myQueue = asyncio.Queue(loop=loop, maxsize=10)
    try:
        loop.run_until_complete(asyncio.gather(
            newsProducer(myQueue),
            newsConsumer("A", myQueue),
            newsConsumer("B", myQueue),
        ))
    except KeyboardInterrupt:
        asyncio.Task.all_tasks()
        asyncio.gather(*asyncio.Task.all_tasks()).cancel()
        loop.stop()
        # loop.run_forever()  # 在jupyter不能手动关闭
    finally:
        pass
        # loop.close()  # 在jupyter不能手动关闭





    2019-11-15 16:01:57,574 10912 13460 [*] 消费者: A 试图从队列中获取
    2019-11-15 16:01:57,592 10912 13460 [*] 消费者: B 试图从队列中获取
    2019-11-15 16:01:58,577 10912 13460 [*] 将产品放入队列1
    2019-11-15 16:01:58,584 10912 13460 [*] 消费者: A 消耗了ID的商品: 1
    2019-11-15 16:01:58,589 10912 13460 [*] 消费者: A 试图从队列中获取
    2019-11-15 16:01:59,580 10912 13460 [*] 将产品放入队列4
    2019-11-15 16:01:59,585 10912 13460 [*] 消费者: B 消耗了ID的商品: 4
    2019-11-15 16:01:59,590 10912 13460 [*] 消费者: B 试图从队列中获取
    2019-11-15 16:02:00,598 10912 13460 [*] 将产品放入队列1
    2019-11-15 16:02:00,604 10912 13460 [*] 消费者: A 消耗了ID的商品: 1
    2019-11-15 16:02:00,609 10912 13460 [*] 消费者: A 试图从队列中获取
    2019-11-15 16:02:01,602 10912 13460 [*] 将产品放入队列2
    2019-11-15 16:02:01,610 10912 13460 [*] 消费者: B 消耗了ID的商品: 2
    2019-11-15 16:02:01,618 10912 13460 [*] 消费者: B 试图从队列中获取
    2019-11-15 16:02:02,609 10912 13460 [*] 将产品放入队列2
    2019-11-15 16:02:02,619 10912 13460 [*] 消费者: A 消耗了ID的商品: 2
    2019-11-15 16:02:02,626 10912 13460 [*] 消费者: A 试图从队列中获取
    2019-11-15 16:02:03,618 10912 13460 [*] 将产品放入队列1
    2019-11-15 16:02:03,626 10912 13460 [*] 消费者: B 消耗了ID的商品: 1
    2019-11-15 16:02:03,631 10912 13460 [*] 消费者: B 试图从队列中获取
    2019-11-15 16:02:04,622 10912 13460 [*] 将产品放入队列5
    2019-11-15 16:02:04,628 10912 13460 [*] 消费者: A 消耗了ID的商品: 5
    2019-11-15 16:02:04,632 10912 13460 [*] 消费者: A 试图从队列中获取
    2019-11-15 16:02:05,623 10912 13460 [*] 将产品放入队列3
    2019-11-15 16:02:05,631 10912 13460 [*] 消费者: B 消耗了ID的商品: 3
    2019-11-15 16:02:05,634 10912 13460 [*] 消费者: B 试图从队列中获取
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值