Вопрос проверяет понимание низкоуровневой основы асинхронного ввода-вывода и связи Python с механизмами операционной системы.
Файловый дескриптор — это числовой идентификатор ресурса в операционной системе. В асинхронности именно через файловые дескрипторы ОС сообщает, готов ли ресурс к чтению или записи. Асинхронный код не ждёт выполнения операции, а ожидает событие от дескриптора. Это позволяет обслуживать множество соединений в одном потоке. Без файловых дескрипторов event loop не смог бы работать эффективно.
Асинхронность в Python опирается не на магию языка, а на механизмы операционной системы.
Файловый дескриптор — это идентификатор, через который процесс взаимодействует с ресурсом.
К таким ресурсам относятся:
сетевые сокеты
файлы
pipe и каналы
stdin / stdout
Любой сокет в итоге — это файловый дескриптор.
Асинхронный код не может постоянно проверять «готово ли чтение». Вместо этого он говорит ОС:
«сообщи, когда этот дескриптор будет готов»
«пока что я займусь другими задачами»
ОС отслеживает состояние дескрипторов и уведомляет event loop.
Event loop:
Регистрирует файловые дескрипторы
Передаёт их в epoll / kqueue
Засыпает до появления событий
Получает список готовых дескрипторов
Возобновляет соответствующие задачи
Файловые дескрипторы — это точка контакта между асинхронным Python-кодом и ядром ОС. Без них невозможно реализовать эффективный event loop.