有人能解释一下为什么coro2整理和coro1整理之间有5秒钟的延迟吗?
另外,如果我用asyncio.wait([asyncio.sleep(5)])替换asyncio.sleep(5),为什么没有这样的延迟?
async def coro1():
logger.info("coro1 start")
await asyncio.wait([asyncio.sleep(5)])
logger.info("coro1 finish")
async def coro2():
logger.info("coro2 start")
time.sleep(10)
logger.info("coro2 finish")
async def main():
await asyncio.gather(coro1(), coro2())
loop = asyncio.get_event_loop()
loop.run_until_complete(main())2020-05-25 12:44:56 coro1 start
2020-05-25 12:44:56 coro2 start
2020-05-25 12:45:06 coro2 finish
2020-05-25 12:45:11 coro1 finish发布于 2020-05-25 12:11:30
TLDR:不要在协同线中使用阻塞调用(如time.sleep )。使用asyncio.sleep异步暂停,如果必须运行阻塞代码,则使用事件循环执行器。
使用asyncio.wait([thing])添加一个间接级别,在一个新的未来/任务中执行thing。当一个裸的await asyncio.sleep(5)在coro1期间执行睡眠时,包装的await asyncio.wait([asyncio.sleep(5)])在所有其他当前计划的协同线之后执行睡眠。
async def coro1():
logger.info("coro1 start")
await asyncio.sleep(5) # started immediately
logger.info("coro1 finish")
async def coro1():
logger.info("coro1 start")
await asyncio.wait([ # started immediately
asyncio.sleep(5) # started in new task
])
logger.info("coro1 finish")因为coro2使用阻塞time.sleep(10),所以它禁用事件循环和所有其他协同。
async def coro2():
logger.info("coro2 start")
time.sleep(10) # nothing happens for 10 seconds
logger.info("coro2 finish")这阻止了未来的进一步启动--包括asyncio.wait的新未来--以及恢复--包括光秃秃的asyncio.sleep(5)。在前一种情况下,这意味着asyncio.sleep在time.sleep完成后启动-因此需要10 + 5秒来完成。在后一种情况下,这意味着asyncio.sleep已经启动,它只是不能在10秒结束之前完成-因此需要max(10, 5)秒来完成。
始终如一地使用asyncio.sleep获得所需的持续时间。如果必须执行阻塞代码,请让它执行通过遗嘱执行人运行。
async def coro1w():
print("coro1w start", time.asctime())
await asyncio.wait([asyncio.sleep(5)])
print("coro1w finish", time.asctime())
async def coro1b():
print("coro1b start", time.asctime())
await asyncio.sleep(5)
print("coro1b finish", time.asctime())
async def coro2a():
print("coro2a start", time.asctime())
await asyncio.sleep(10) # asynchronous sleep
print("coro2a finish", time.asctime())
async def coro2t():
print("coro2t start", time.asctime())
loop = asyncio.get_running_loop() # threaded sleep
await loop.run_in_executor(None, lambda: time.sleep(10))
print("coro2t finish", time.asctime())
async def main():
await asyncio.gather(coro1w(), coro1b(), coro2a(), coro2t())
asyncio.run(main())https://stackoverflow.com/questions/62001898
复制相似问题