我有一个存储在Redis列表中的队列。我正在尝试为此队列创建异步使用者。但是无法在循环内调用异步函数。当我打电话时,它的工作方式类似于同步功能。
import asyncio
async def worker():
print("starting sleep")
await asyncio.sleep(2)
print("slept")
async def main():
while True:
await worker()
asyncio.run(main())
这里是实现地雷的简短示例。我希望看到“开始睡眠”消息,直到出现第一条“睡眠”消息,这意味着2秒钟。
答案 0 :(得分:1)
main
实际上是await
worker
的完成。在worker
完成之前,main
将不会进行。 async
任务不会像多线程那样在后台运行。
您想要的是继续发动新员工,而无需await
雇用他们中的每一个。但是,如果您只是在这样的循环中继续这样做:
while True:
worker()
然后,您将永远看不到这些工作程序的任何输出,因为这是一个无休止的循环,永远不会给其他任何运行的机会。您需要以某种方式“打破”这个循环,以允许工作人员进步。这是一个示例:
import asyncio
async def worker():
print("starting sleep")
await asyncio.sleep(2)
print("slept")
async def main():
while True:
asyncio.ensure_future(worker())
await asyncio.sleep(0.5)
asyncio.run(main())
这将产生预期的结果:
starting sleep
starting sleep
starting sleep
starting sleep
slept
starting sleep
slept
...
await
中的main
将控制权转移回事件循环,该循环现在有机会运行堆积的worker
任务,当这些工人任务await
时,他们依次将控制权转移回事件循环,并在完成main
的睡眠后将其转移回worker
或await
。
请注意,这仅是出于说明目的;如果并且当您中断该程序时,您会看到有关尚未完成的未完成任务的通知。您应该跟踪自己的任务,并await
将它们全部完成以在某个地方结束。
答案 1 :(得分:1)
以下是使用asyncio.wait
的示例:
import asyncio
async def worker():
print("starting sleep")
await asyncio.sleep(2)
print("slept")
async def main():
tasks = [worker() for each in range(10)]
await asyncio.wait(tasks)
asyncio.run(main())
它催生了所有的工人。