如果只有一个线程,异步任务如何说它们是 "done"?
How do asynchronous tasks say they're "done" if there's one thread?
我已经使用 Tornado 和 asyncio 编写了异步程序,但是我意识到我不明白异步任务是如何表示它们已完成的。
例如,让我们看一下http://www.tornadoweb.org/en/stable/guide/async.html#examples中的异步获取。
目前我的理解是:
- 处理程序在
fetch
产生 Future
时挂起。
Future
通过 http://www.tornadoweb.org/en/stable/ioloop.html#tornado.ioloop.IOLoop.add_future 添加到 IOLoop
Future
完成,IOLoop
安排协程重新激活以便完成。
我不明白的是 Future
在步骤 3 "finishes" 中如何调用它的 done callback。我以为只有一个线程,那么 Future
"work in the background" 如何获得控制权以便调用回调?
IOLoop 打开一个套接字到您要从中获取的远程服务器,并使用 epoll 或类似的系统调用将该套接字添加到它正在等待 IO 的文件描述符列表中。
每当循环不执行您的代码时——例如,当您的处理程序被 yield
暂停时,循环正在等待 IO,此处:
https://github.com/tornadoweb/tornado/blob/master/tornado/ioloop.py#L862
当它接收到一个 IO 事件时——例如,当远程服务器发送一些响应字节时——Tornado 找到等待该事件的回调并执行它。
有关事件循环的示例实现,请参阅 A Web Crawler With asyncio Coroutines。
我已经使用 Tornado 和 asyncio 编写了异步程序,但是我意识到我不明白异步任务是如何表示它们已完成的。
例如,让我们看一下http://www.tornadoweb.org/en/stable/guide/async.html#examples中的异步获取。
目前我的理解是:
- 处理程序在
fetch
产生Future
时挂起。 Future
通过 http://www.tornadoweb.org/en/stable/ioloop.html#tornado.ioloop.IOLoop.add_future 添加到 Future
完成,IOLoop
安排协程重新激活以便完成。
IOLoop
我不明白的是 Future
在步骤 3 "finishes" 中如何调用它的 done callback。我以为只有一个线程,那么 Future
"work in the background" 如何获得控制权以便调用回调?
IOLoop 打开一个套接字到您要从中获取的远程服务器,并使用 epoll 或类似的系统调用将该套接字添加到它正在等待 IO 的文件描述符列表中。
每当循环不执行您的代码时——例如,当您的处理程序被 yield
暂停时,循环正在等待 IO,此处:
https://github.com/tornadoweb/tornado/blob/master/tornado/ioloop.py#L862
当它接收到一个 IO 事件时——例如,当远程服务器发送一些响应字节时——Tornado 找到等待该事件的回调并执行它。
有关事件循环的示例实现,请参阅 A Web Crawler With asyncio Coroutines。