1

我已經編寫了使用Tornado和asyncio的異步程序,但是我意識到我不明白異步任務是如何完成的。如果有一個線程,異步任務如何表示它們「完成」?

例如,讓我們看看http://www.tornadoweb.org/en/stable/guide/async.html#examples中的異步獲取。

我的理解迄今爲止是:當fetch產生一個Future

  1. 該處理程序被掛起。
  2. Future經由http://www.tornadoweb.org/en/stable/ioloop.html#tornado.ioloop.IOLoop.add_future
  3. Future完成加入IOLoop,並且IOLoop時間表被重新加進的協程,因此它可以完成。

我不明白的是Future如何在第3步「完成」並調用其done callback。我以爲只有一個線程,那麼Future將如何「在後臺工作」並獲得控制權,以便能夠調用回調函數?

回答

2

IOLoop會打開一個到您正在讀取的遠程服務器的套接字,並將該套接字添加到使用epoll或類似系統調用等待IO的文件描述符列表中。

每當循環不執行你的代碼 - 例如,當你的處理程序由yield暫停,循環正在等待IO,在這裏:

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

當它接收到的IO事件 - - 例如,當遠程服務器發送一些響應字節時 - Tornado找到正在等待該事件並執行它的回調。

有關事件循環的示例實現,請參閱A Web Crawler With asyncio Coroutines