是否可以在一个事件循环中在不同任务上共享asyncio.Queue?
用例:
两项任务正在将数据发布到队列中,一项任务是从队列中获取新项目。所有任务以异步方式。
main.py
import asyncio
import creator
async def pull_message(queue):
while True:
# Here I dont get messages, maybe the queue is always
# occupied by a other task?
msg = await queue.get()
print(msg)
if __name__ == "__main__"
loop = asyncio.get_event_loop()
queue = asyncio.Queue(loop=loop)
future = asyncio.ensure_future(pull_message(queue))
creators = list()
for i in range(2):
creators.append(loop.create_task(cr.populate_msg(queue)))
# add future to creators for easy handling
creators.append(future)
loop.run_until_complete(asyncio.gather(*creators))
creator.py
import asyncio
async def populate_msg(queue):
while True:
msg = "Foo"
await queue.put(msg)
答案 0 :(得分:1)
您的代码中的问题是populate_msg
不会屈服于事件循环,因为队列是无界的。这有点违反直觉,因为协程显然包含await
,但是如果协程否则会阻塞await
,则put()
仅暂停执行协程。由于无限制队列上的populate_msg
永远不会阻塞,因此populate_msg
是事件循环执行的唯一操作。
将await asyncio.sleep(0)
更改为实际执行其他操作(例如等待网络事件)后,问题将消失。出于测试目的,您可以在循环内部添加while
,这将迫使协程在array
(
[0] => apple,
[1] => orange,
)
循环的每次迭代中对事件循环产生控制。请注意,这将导致事件循环通过不断旋转循环来消耗整个内核。