Наша предыдущая статья была посвящена теме Асинхронное программирование на основе потоков. По мере продвижения вперед давайте рассмотрим истинную неблокирующую природу асинхронного программирования и то, как прерывания ввода-вывода как события используются для создания систем, способных выдерживать огромные рабочие нагрузки.
Что такое событийное программирование?
Благодаря стилю, основанному на событиях, мы гарантируем, что наше приложение не содержит блокирующего кода. После инициирования операции ввода-вывода, такой как вызов базы данных, поток переключается на другие задачи. Затем этот поток уведомляется/прерывается, когда операция ввода-вывода завершается, поэтому он может обрабатывать результаты. С точки зрения вызывающего потока весь этап ввода-вывода передается кому-то другому, который отправит уведомление, когда задание будет выполнено.
Как видите, это очень похоже на то, что мы обсуждали в нашем обсуждении асинхронного программирования на основе потоков. Принципиальное различие между пулом потоков и этой моделью заключается в том, что модель на основе пула потоков делает вид, что она не заблокирована, но на самом деле ее блок просто передается какому-то другому потоку, тогда как в этой модели вообще нет блокирующего кода. Нет необходимости иметь пул потоков на другой стороне вызывающего потока для получения и уведомления вызывающего. Вопрос, однако, в том, кто выдает прерывание после завершения операции ввода-вывода.
Как работает программирование на основе событий?
UNIX и его производные поддерживают прием перехватчика ввода-вывода от приложения, отслеживание жизненного цикла ввода-вывода и уведомление приложения о завершении ввода-вывода. Используя эту функцию, приложение может затем сосредоточиться на запуске ввода-вывода и обработке его результатов, а не беспокоиться об управлении вводом-выводом. libuv библиотека C, изначально написанная на C для Node.js, абстрагируется от того же управления вводом-выводом.
Ввод-вывод выполняется путем открытия сокета и выдачи системного вызова, чтобы начать отправку и получение данных через этот сокет. Когда запрошенные данные отправляются, приложение, использующее модель «один поток на запрос», просто опрашивает сокет, чтобы проверить, когда оно получило результат.
В ОС встроена программа опроса, которая может очень эффективно обрабатывать опрос сокетов. Наше приложение регистрирует свой собственный сокет как опрашиваемый сокет и дает ему хук, т. е. обратный вызов, который ОС использует для уведомления приложения, когда сокет получает ответ, как только входящий поток данных готов к обработке. Теперь, когда поток приложения свободен, его можно использовать для обработки задач, не связанных с вводом-выводом, поскольку блокирующий ввод-вывод отсутствует, что позволяет ему достичь массового масштаба. В библиотеке libuv epoll выполняет опрос этих сокетов ввода-вывода.
Все сокеты, зарегистрированные в epoll, постоянно опрашиваются, обычно через один поток. С данными ответа и контекстом выполнения потока (также сохраненным здесь потоком приложения при передаче в epoll) epoll вызывает обратный вызов, переданный ему потоком приложения. В результате поток приложения будет прерван для обработки вывода, чтобы возобновить поток выполнения с этой точки.
При использовании стиля, основанного на событиях, передача задач и прерывания потоков происходят на границе между приложением и ОС. Этот обмен известен как цикл событий.
Epoll по-прежнему должен запускать поток для опроса всех сокетов, что по сути является блокирующей операцией. Разве это не то же самое, что и пулы потоков (только один поток в пуле)?
Это правильно, но мы (приложение) больше этого не делаем. Наше приложение полностью управляемо событиями. ОС чрезвычайно эффективно справляется с такими низкоуровневыми действиями, как опрос сокетов.
Я хотел бы услышать от вас. Вы можете связаться со мной по любому вопросу, оставить отзыв или просто обсудить вопросы по следующим каналам: Отправьте мне сообщение в Linkedin или напишите мне по адресу [email protected]
Бит: почувствуйте мощь компонентно-ориентированной разработки
Скажи привет Bit. Это инструмент №1 для разработки приложений на основе компонентов.
С помощью Bit вы можете создать любую часть своего приложения в виде «компонента», который можно компоновать и использовать повторно. Вы и ваша команда можете совместно использовать набор инструментов для совместной разработки большего количества приложений.
- Создавайте и компонуйте «строительные блоки приложения»: элементы пользовательского интерфейса, полные функции, страницы, приложения, бессерверные или микросервисы. С любым стеком JS.
- С легкостью делитесь и повторно используйте компоненты в команде.
- Быстро обновляйте компоненты в разных проектах.
- Делайте сложные вещи простыми: Монорепо, дизайн-системы и микрофронтенды.
Попробуйте Bit бесплатно и с открытым исходным кодом→