如果有一个线程,异步任务如何说它们"done"?



我使用Tornado和asyncio编写了异步程序,但是我意识到我不理解异步任务是如何完成的。

例如,让我们看一下http://www.tornadoweb.org/en/stable/guide/async.html#examples中的异步读取。

目前我的理解是:

  1. fetch产生Future时,处理程序被挂起。
  2. Future加入IOLoop通过http://www.tornadoweb.org/en/stable/ioloop.html#tornado.ioloop.IOLoop.add_future
  3. Future完成,IOLoop调度协程重新激活,使其能够完成。

我不明白的是Future在步骤3"完成"并调用它的完成回调。我认为只有一个线程,那么Future如何"在后台工作"并获得控制,以便它可以调用回调?

IOLoop打开一个套接字到您正在获取的远程服务器,并将该套接字添加到文件描述符列表中,它正在使用epoll或类似的系统调用等待IO。

当循环没有执行你的代码时——例如,当你的处理程序被yield暂停时,循环正在等待IO,这里:

https://github.com/tornadoweb/tornado/blob/master/tornado/ioloop.py L862

当它接收到一个IO事件时——例如,当远程服务器发送一些响应字节时——Tornado找到正在等待该事件的回调并执行它。

有关事件循环的示例实现,请参见使用asyncio协程的Web Crawler。

最新更新