1

Я написал асинхронные программы с использованием 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 «заканчивается» и вызывает его done callback. Я думал, что есть только один поток, так как Future «работает в фоновом режиме» и получит контроль, чтобы он мог вызвать обратный вызов?

ответ

2

IOLoop открывает сокет удаленному серверу, который вы извлекаете, и добавляет этот сокет в список дескрипторов файлов, на котором он ожидает ввода-вывода, используя epoll или аналогичный системный вызов.

Всякий раз, когда цикл не выполняется код - например, когда обработчик приостановлено по yield, петля ждет ввода-вывода, здесь:

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

Когда он получает событие IO - - например, когда удаленный сервер отправляет несколько байтов ответа - Tornado находит обратный вызов, ожидающий этого события, и выполняет его.

Пример реализации цикла событий см. В разделе A Web Crawler With asyncio Coroutines.