python里使用队列asyncio.Queue进行通讯

本文通过一个具体的示例介绍了Python中asyncio.Queue的用法,包括如何创建队列、添加任务以及停止信号的处理方式。该示例展示了多个消费者和生产者如何协同工作。

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

asyncio.Queue与其它队列是一样的,都是先进先出,它是为协程定义的,例子如下:

import asyncio


async def consumer(n, q):
    print('consumer {}: starting'.format(n))
    while True:
        print('consumer {}: waiting for item'.format(n))
        item = await q.get()
        print('consumer {}: has item {}'.format(n, item))
        if item is None:
            # None is the signal to stop.
            q.task_done()
            break
        else:
            await asyncio.sleep(0.01 * item)
            q.task_done()
    print('consumer {}: ending'.format(n))


async def producer(q, num_workers):
    print('producer: starting')
    # Add some numbers to the queue to simulate jobs
    for i in range(num_workers * 3):
        await q.put(i)
        print('producer: added task {} to the queue'.format(i))
    # Add None entries in the queue
    # to signal the consumers to exit
    print('producer: adding stop signals to the queue')
    for i in range(num_workers):
        await q.put(None)
    print('producer: waiting for queue to empty')
    await q.join()
    print('producer: ending')


async def main(loop, num_consumers):
    # Create the queue with a fixed size so the producer
    # will block until the consumers pull some items out.
    q = asyncio.Queue(maxsize=num_consumers)

    # Scheduled the consumer tasks.
    consumers = [
        loop.create_task(consumer(i, q))
        for i in range(num_consumers)
    ]

    # Schedule the producer task.
    prod = loop.create_task(producer(q, num_consumers))

    # Wait for all of the coroutines to finish.
    await asyncio.wait(consumers + [prod])


event_loop = asyncio.get_event_loop()
try:
    event_loop.run_until_complete(main(event_loop, 2))
finally:
    event_loop.close()
输出如下:

consumer 0: starting
consumer 0: waiting for item
consumer 1: starting
consumer 1: waiting for item
producer: starting
producer: added task 0 to the queue
producer: added task 1 to the queue
consumer 0: has item 0
consumer 1: has item 1
producer: added task 2 to the queue
producer: added task 3 to the queue
consumer 0: waiting for item
consumer 0: has item 2
producer: added task 4 to the queue
consumer 1: waiting for item
consumer 1: has item 3
producer: added task 5 to the queue
producer: adding stop signals to the queue
consumer 0: waiting for item
consumer 0: has item 4
consumer 1: waiting for item
consumer 1: has item 5
producer: waiting for queue to empty
consumer 0: waiting for item
consumer 0: has item None
consumer 0: ending
consumer 1: waiting for item
consumer 1: has item None
consumer 1: ending
producer: ending

Python游戏开发入门

你也能动手修改C编译器

纸牌游戏开发

http://edu.youkuaiyun.com/course/detail/5538 

五子棋游戏开发

http://edu.youkuaiyun.com/course/detail/5487
RPG游戏从入门到精通
http://edu.youkuaiyun.com/course/detail/5246
WiX安装工具的使用
http://edu.youkuaiyun.com/course/detail/5207
俄罗斯方块游戏开发
http://edu.youkuaiyun.com/course/detail/5110
boost库入门基础
http://edu.youkuaiyun.com/course/detail/5029
Arduino入门基础
http://edu.youkuaiyun.com/course/detail/4931
Unity5.x游戏基础入门
http://edu.youkuaiyun.com/course/detail/4810
TensorFlow API攻略
http://edu.youkuaiyun.com/course/detail/4495
TensorFlow入门基本教程
http://edu.youkuaiyun.com/course/detail/4369
C++标准模板库从入门到精通 
http://edu.youkuaiyun.com/course/detail/3324
跟老菜鸟学C++
http://edu.youkuaiyun.com/course/detail/2901
跟老菜鸟学python
http://edu.youkuaiyun.com/course/detail/2592
在VC2015里学会使用tinyxml库
http://edu.youkuaiyun.com/course/detail/2590
在Windows下SVN的版本管理与实战 
http://edu.youkuaiyun.com/course/detail/2579
Visual Studio 2015开发C++程序的基本使用 
http://edu.youkuaiyun.com/course/detail/2570
在VC2015里使用protobuf协议
http://edu.youkuaiyun.com/course/detail/2582
在VC2015里学会使用MySQL数据库
http://edu.youkuaiyun.com/course/detail/2672




<think>我们正在讨论asyncio.Queue的当前队列长度获取方法。根据引用[1]中的代码示例,我们看到在生产者向队列添加任务时,使用了`awaitqueue.put(i)`,而在消费者中使用了`item=awaitqueue.get()`。但是,如何获取当前队列的长度呢?在Pythonasyncio.Queue中,有一个方法`qsize()`可以返回队列的当前大小(即队列中的元素数量)。但是需要注意的是,由于asyncio.Queue是为异步编程设计的,它可能会被多个协程同时操作,因此获取的队列大小可能瞬间就会改变。根据引用[3]中的代码片段,我们看到有:size=queue.qsize()这直接使用了`qsize()`方法来获取队列的当前长度。因此,要获取asyncio.Queue的当前队列长度,我们可以使用`qsize()`方法。例如:current_size=queue.qsize()需要注意的是,`qsize()`方法返回一个整数,表示队列中的项目数。另外,引用[4]中提到,队列有一个未完成任务的计数(即通过`task_done()`和`join()`来管理)。但`qsize()`只反映当前队列中待处理的项目数量,不包括已经被取出但尚未标记为完成(即尚未调用`task_done()`)的项目。不过,在队列中,被取出的项目会立即从队列中移除,所以`qsize()`反映的是队列中实际存在的项目数。因此,我们可以总结如下:-使用`asyncio.Queue`实例的`qsize()`方法可以获取当前队列中的项目数量。示例代码片段:importasyncioasyncdefmain():queue=asyncio.Queue()awaitqueue.put(1)awaitqueue.put(2)print("Currentqueuesize:",queue.qsize())#输出2asyncio.run(main())注意:`qsize()`是立即返回的,不需要await,因为它不是异步方法。但是,根据Python官方文档,`asyncio.Queue.qsize()`返回队列的大小。注意,在并发环境中,这个值只能作为近似值使用,因为在获取后,队列大小可能立即被其他协程改变。因此,在需要精确控制时,可能需要结合其他同步机制,但在大多数情况下,`qsize()`足以提供当前队列的大致情况。另外,引用[3]中的示例代码还展示了如何根据队列大小动态调整信号量的值,这也说明了`qsize()`的使用场景。所以,用户问题的答案是:使用`asyncio.Queue`的`qsize()`方法。根据要求,我们生成相关问题:1.asyncio.Queue的qsize()方法队列为空时返回什么?2.除了qsize(),asyncio.Queue还有哪些常用方法?3.如何等待asyncio.Queue变为非空状态?</think>### 如何获取 asyncio.Queue 的当前队列长度 在 Python 的 `asyncio.Queue` 中,获取当前队列长度的方法非常简单直接: ```python current_size = queue.qsize() ``` #### 关键特性说明: 1. **同步方法** `qsize()` 是**同步方法**(无需 `await`),直接返回队列中的元素数量: ```python print(f"当前队列长度: {queue.qsize()}") # 输出整数 ``` 2. **实时反映状态** 返回值是调用时刻队列中的确切元素数量,但需注意并发场景下该值可能快速变化[^1][^4]。 3. **空队列行为** 当队列为空时,`qsize()` 返回 `0`。 #### 完整示例: ```python import asyncio async def main(): queue = asyncio.Queue(maxsize=100) # 添加任务 for i in range(5): await queue.put(i) print(f"添加后队列长度: {queue.qsize()}") # 输出 1,2,3,4,5 # 消费任务 while not queue.empty(): item = await queue.get() print(f"获取 {item} 后队列长度: {queue.qsize()}") # 长度递减 queue.task_done() asyncio.run(main()) ``` #### 注意事项: - **并发准确性**:在多个协程同时操作队列时,`qsize()` 的返回值是瞬时状态,可能在被使用时已发生变化[^1][^4]。 - **性能**:`qsize()` 操作是 $O(1)$ 时间复杂度,高效无阻塞。 - **对比 `empty()`**:若只需判断队列是否为空,可用更语义化的 `queue.empty()` 方法。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caimouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值