Как устроен цикл событий asyncio
Вопрос
Расскажите, как устроен цикл событий asyncio и как он узнаёт, что сокет готов.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Очередь готовых колбэков и куча таймеров
Селектор ОС (epoll, kqueue) ждёт готовности сокетов
Задача это корутина, которая продвигается вызовами `send` до следующего `await`
Future: результат, который появится позже, задача подписывается на него
Одна итерация: выполнить готовое, посчитать таймаут, спросить селектор
Блокирующий вызов не даёт циклу дойти до селектора
Что могут спросить следом
- Что такое uvloop?
- Как работает
asyncio.sleep(0)?
Разбор
Образцовый ответ: «Цикл событий держит очередь готовых к выполнению колбэков и кучу запланированных по времени. Задача это обёртка над корутиной: цикл вызывает у корутины send, она выполняется до await на объекте, который ещё не готов, обычно это Future, и задача подписывается на его завершение. Когда сокет нужно прочитать, транспорт регистрирует его в селекторе ОС: epoll на Linux, kqueue на macOS. Каждая итерация цикла выполняет все готовые колбэки, затем вычисляет, сколько можно ждать до ближайшего таймера, и вызывает селектор с этим таймаутом. Селектор возвращает готовые сокеты, их колбэки завершают соответствующие Future, и ожидающие задачи снова попадают в очередь готовых. asyncio.sleep(0) просто отдаёт управление на одну итерацию. Если корутина вызвала блокирующий код, цикл не дойдёт до селектора, и все задачи замрут. uvloop это замена стандартного цикла на базе libuv, заметно быстрее, её часто ставят с uvicorn».
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.