While循环内的异步函数调用

时间:2020-06-05 14:58:42

标签: python asynchronous

我有一个存储在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秒钟。

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的睡眠后将其转移回workerawait

请注意,这仅是出于说明目的;如果并且当您中断该程序时,您会看到有关尚未完成的未完成任务的通知。您应该跟踪自己的任务,并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())

它催生了所有的工人。