繁体   English   中英

asyncio 如何理解非阻塞操作的任务已完成

[英]How asyncio understands that task is complete for non-blocking operations

我试图了解 asyncio 是如何工作的。 至于 I/O 操作,我了解到,当调用 await 时,我们在 EventLoop 中注册 Future object,然后调用 epoll 获取属于 Future 对象的 sockets,准备给我们数据。 在我们运行注册的回调并恢复 function 执行之后。

但是,我无法理解的是,如果我们使用 await 而不是 I/O 操作会发生什么。 eventloop 如何理解该任务已完成? 它是为此创建套接字还是使用另一种循环? 它使用epoll吗? 或者它不添加到循环并将其用作生成器?

有一个例子:

import asyncio

async def test():
    return 10



async def my_coro(delay):
    loop = asyncio.get_running_loop()
    end_time = loop.time() + delay
    while True:
        print("Blocking...")
        await test()
        if loop.time() > end_time:
            print("Done.")
            break
async def main():
    await my_coro(3.0)

asyncio.run(main())

await不会自动屈服于事件循环,这只发生在异步 function(等待链中的任何位置)请求暂停时,通常是由于 IO 或超时未准备好。

在您的示例中,事件循环永远不会返回,您可以通过在while循环之前移动“阻塞”打印并将main更改为await asyncio.gather(my_coro(3.0), my_coro(3.0))轻松验证。 您将观察到协同程序是串行执行的(“阻塞”后跟“完成”,都重复两次),而不是并行执行(“阻塞”后跟另一个“阻塞”,然后两次“完成”)。 原因是根本没有机会进行上下文切换 - my_coro在一个 go 中执行,就好像它们是普通的 function 一样,因为它的等待都没有选择暂停。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM