TGStat
TGStat
Qidiruv uchun matnni kiriting
Ilg‘or kanal qidiruvi
  • flag Uzbek
    Sayt tili
    flag Russian flag English flag Uzbek
  • Saytga kirish
  • Katalog
    Kanal va guruhlar katalogi Hududiy to‘plamlar Tematik to‘plamlar Платные каналы Kanallar qidiruvi
    Kanal/guruh qo‘shish
  • Reytinglar
    Kanallar reytingi Guruhlar reytingi Postlar reytingi
    Brendlar va shaxslar reytingi
  • Analitika
  • Postlarda qidiruv
  • Telegram'ni kuzatish
  • Targ‘ibot
    Yandex Business orqali reklama TGStat Agency orqali kanallarda reklama TGStat.ru saytida reklama
Советы разработчикам (python и не только)

4 Nov 2025, 15:30

Telegram'da ochish Ulashish Shikoyat qilish

Asyncio и колбэки

В прошлом посте мы рассмотрели как asyncio взаимодействует с генераторами, но на более низком уровне он взаимодействует с колбэками, а генераторы и корутины - вспомогательные возможности для более удобного написания кода.

Базовая функциональность лупа заключается в том, что он умеет вызывать в цикле синхронные функции. Пока один колбэк не отработает, луп не перейдет к другому. Такие функции можно добавить через вызов loop.call_soon (или loop.call_soon_threadsafe, если мы хотим это сделать из другого потока). Дополнительно, у него есть некоторые другие функции вроде задания задержки вызова функции.

Следующий важный объект - Future. Его задача достаточно простая - хранить некоторый результат и вызывать колбэк при его установке. И все ещё это обычная синхронная функция, но уже вызывающаяся не планировщиком лупа, а напрямую, когда кто-то делает set_result

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

В качестве клея между асинк функциями (читай генераторами) и логикой вызова функций лупом выступает объект Task. Таск добавляет свой метод как колбэк в лупе и когда луп вызовет его, он промотает внутренний генератор на шаг вперед. Если при этом встретится Future, таск зарегистрируется в нем на ожидание результата и, таким образом, шаг будет завершен и управление вернется в луп. Когда кто-то установит результат на футуре, он сразу обратится к нашему таску и сможет передать ему управление.

При этом возникает важный вопрос, а кто пометит футуру завершенной? У нас есть несколько вариантов:

• Другой таск или колбэк, просто вызвав set_result
• Другой поток (так как объекты asyncio не потокобезопасны, это будет сделано через call_soon_threadsafe). Например, так работает aiofiles или granian.
• Сам луп согласно своей внутренней логике

Asyncio loop имеет множество методов, которые возвращают Future объекты и при этом включают какую-то внутреннюю логику. Одна из важнейших функций - работа с сокетами. Операционная система имеет два режима работы с сокетами - блокирующий и неблокирующий. В блокирующем режиме наши вызовы send/recv блокируют тред пока сокет не будет готов, в неблокирующем же - мы сразу получим предложение повторить вызов позже. Благодаря этому можно во время ожидания переключиться на другую работу. Дополнительно, ОС имеют разные варианты API для опроса сокетов на предмет доступности (вы, конечно, можете пытаться делать send/recv на каждом в цикле, но это очень не эффективно): select, epoll, kqueue, IOCP.

Таким образом, loop имеет методы вида sock_recv, sock_sendall которые возвращают Future и говорят лупу заниматься обслуживанием таких сокетов (опрашивать готовность и собственно передать данные). Дальнейшее поведение лупа будет зависеть от реализации, но в случае Linux это будет вызов epoll между вызовами колбэков. Как только чтение/запись в сокет будет завершено, луп сам (или какая-то его подсистема, например Транспорт) установит результат футуре. Аналогично можно работать с pipe и сабпроцессами.

Кратко:
1. Loop умеет вызывать синхронные колбэки
2. Future хранит результат и вызывает колбэки
3. Task адаптирует генератор под колбэки лупа и связывает с футурами
4. Loop сам опрашивает сокеты в неблокирующем режиме и обновляет футуры
5. Футуры можно обновлять из других колбэков или тредов

Дополнительные материалы:
• https://peps.python.org/pep-3156
• https://learn.microsoft.com/en-us/windows/win32/fileio/i-o-completion-ports
• https://www.kegel.com/c10k.html
• https://man7.org/linux/man-pages/man7/io_uring.7.html

5k 1 78 33 81
Katalog
Kanal va guruhlar katalogi Kanallar to‘plamlari Kanallar qidiruvi Kanal/guruh qo‘shish
Reytinglar
Telegram-kanallar reytingi Telegram-guruhlar reytingi Postlar reytingi Brendlar va shaxslar reytingi
API
Statistika API'si Postlar qidiruvi API'si API Callback
Kanallarimiz
@TGStat @TGStat_Chat @telepulse @TGStatAPI
O‘qish
Академия TGStat Telegram tadqiqoti 2019 Telegram tadqiqoti 2021 Telegram tadqiqoti 2023
Kontaktlar
Справочный центр Qo‘llab-quvvatlash Email Vakansiyalar
Har xil narsalar
Foydalanuvchi shartnomasi Maxfiylik siyosati Ommaviy oferta
Botlarimiz
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot