DollyPapper
@DollyPapper

Как всё таки работает асинхронность?

Привет. Пытаюсь для себя всё таки разобраться как под капотом работает асинхронность.
  1. Верно ли я понимаю, что полное название асинхронности это Асинхронный I/O и именно I/O операции могут быть асинхронными?
  2. Исходя из первого вопроса и концепции "Всё есть файл" вся асинхронность строится на API мультиплексированного ввода-вывода ОС (pool/select/epool | KQueue | что-то аналогичное в винде) который предоставляет ОС?
    Судя например по описанию NodeJS, а вернее libuv который реализует eventloop
libuv is a multi-platform C library that provides support for asynchronous I/O based on event loops. It supports epoll(4), kqueue(2), Windows IOCP, and Solaris event ports

моя догадка верна.

Понимаю, что выглядит так, как будто и вопроса тут никакого нет, просто хочу удостоверится и получить ответ от знающий людей, прав ли я в том, что я написал, или ошибаюсь.
  • Вопрос задан
  • 581 просмотр
Решения вопроса 3
Alexandroppolus
@Alexandroppolus
кодир
То что написано - это асинхронный I/O. Может ещё быть асинхронное вычисление, запускаемое в отдельном потоке. Ещё бывает дурацкий вариант, когда синхронное I/O запускается в отдельном потоке, который просто ждёт.
Ответ написан
@TheAthlete
Perl 5, C, C++, компьютерные сети
Верно ли я понимаю, что полное название асинхронности это Асинхронный I/O и именно I/O операции могут быть асинхронными?

Более точное название (определение) - это неблокирующий ввод-вывод и использование одного из методов мультиплексирования ввода вывода (epoll в linux; kqueue в *BSD-системах; IOCP в Windows). В подавляющем большинстве случаев под неблокирующим вводом-выводом понимается сетевой ввод-вывод. Например создается сокет с помощью системного вызова socket с установкой флага O_NONBLOCK (непосредственно в функции, либо с помощью функции fctl для созданного сокета)

Blocking I/O, Nonblocking I/O, And Epoll
Асинхронный ввод-вывод средствами POSIX
Ответ написан
Комментировать
MvcBox
@MvcBox
Software Developer [C/C++/JS(for Node.js)/etc]
DollyPapper, возможно Вам поможет мой ответ на один из вопросов (там есть продолжение в комментариях) - https://qna.habr.com/q/684952#answer_1481656
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
Vindicar
@Vindicar
RTFM!
Передразнивая одного человека, асинхронность это кооперативная многозадачность плюс цикл обработки событий.

Упрощенно, есть набор функций, умеющих приостанавливать и возобновлять своё выполнение - корутин.
Корутины обычно приостанавливают своё выполнение после запроса операции ввода/вывода, но могут и по другим поводам - например, просто ожидание, или ожидание завершения другой корутины, или ещё что.

Ядром асинхронной программы является паттерн "реактор" - рабочий цикл. В контексте клиентского JS это рабочий цикл браузера, в контексте ноды - что-то отдельное, я полагаю (с нодой не работал).
Цикл делает следующее:
- ожидает завершения одной из операций ввода/вывода или ожидания (любой)
- определяет, какая корутина ожидала эту операцию
- передаёт ей управление
- корутина делает своё дело, обрабатывая результат операции
- потом корутина либо завершается, либо планирует еще одну операцию. И цикл возобновляется.

Отсюда и вытекают все плюсы и минусы. С одной стороны, переключение между корутинами происходит в явно указанные моменты времени, так что меньше возни с синхронизацией.
С другой стороны, длинные вычисления так не распараллелишь - только ввод/вывод. Ну или в длинном вычислении время от времени делать паузу, но выигрыша все равно не будет. Так что это имеет смысл только для IO-bound программ.
Ответ написан
@res2001
Developer, ex-admin
Асинхронным может быть что угодно, просто для ввода/вывода есть средства в ОС, для остального требуется писать самому (используя многопоточность или другой вариант параллельного исполнения) или использовать библиотеки.
В целом принцип такой: вы даете задание и это задание как-то чем-то исполняется, не зависимо от вашего потока, должен быть механизм оповещения/опроса о состоянии задания, возврат ошибок/исключений/результата.

Из всего асинхронного API, которое я видел пожалуй наиболее "асинхронным" является "POSIX asynchronous I/O", это когда вы вызываете асинхронный read/write, а для обратной связи используется сигнал (в винде ничего похожего нет). Он наиболее асинхронный потому, что основному потоку не надо никак опрашивать состояние задания - система сама прерывает поток сигналом в произвольный момент. Этот механизм используется довольно редко. Наиболее употребимы select/poll/epoll, в том же libuv используется poll (в винде IOCP).
Ответ написан
Комментировать
Jeer
@Jeer
уверенный пользователь
мне понравилась коротенькая книжка
Асинхронное программирование в C# 5.0 | Дэвис Алекс
Там всё разложено по полочкам не только под c#, сама концепция
https://www.ozon.ru/product/asinhronnoe-programmir...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы