В чем разница между асинхронными, неблокирующими архитектурами на основе событий?





  1. в чем разница между:





    • асинхронные,


    • Неблокирующий и


    • Event-base архитектуры?



  2. может что-то быть как асинхронные и неблокирующийсобытие на основе)?


  3. что самое важное в программировании, чтобы что-то иметь: асинхронный, неблокирующая и / или событийная база (или все 3)?



Если бы вы могли привести примеры, это было бы здорово.



этот вопрос задают, потому что я читал этот великий StackOverflow статья на аналогичную тему, но она не отвечает на мои вопросы выше.

691   5  

5 ответов:

асинхронные Асинхронный буквально означает не синхронный. Электронная почта асинхронна. Вы отправляете письмо, вы не ожидаете получить ответ сейчас. Но это не является неблокирующим. По сути, это означает архитектуру, в которой" компоненты " отправляют сообщения друг другу, не ожидая немедленного ответа. HTTP-запросы синхронны. Отправьте запрос и получите ответ.

Неблокирующий Этот термин в основном используется с IO. Это означает, что когда вы делаете системный вызов, он немедленно вернется с любым результатом, который он имеет, не переводя ваш поток в спящий режим (с высокой вероятностью). Например, неблокирующие вызовы чтения / записи возвращаются с тем, что они могут сделать, и ожидают, что вызывающий вызов снова выполнит вызов. например, try_lock-это неблокирующий вызов. Он будет заблокирован только в том случае, если замок может быть приобретен. Обычная семантика для системных вызовов-блокировка. read будет ждать, пока у него не появятся некоторые данные и не переведет вызывающий поток в спящий режим.

Event-base Этот термин происходит от libevent. неблокирующее чтение/запись звонков сами по себе бесполезны, потому что они не говорят вам, когда вы должны перезвонить (повтор). select/epoll / IOCompletionPort и т. д.-Это разные механизмы для выяснения из ОС "когда" эти вызовы должны возвращать "интересные" данные. libevent и другие подобные библиотеки предоставляют оболочки над этими средствами мониторинга событий, предоставляемыми различными операционными системами, и дают согласованный API для работы с которой работает в разных операционных системах. Неблокирующий IO идет рука об руку с Event-base.

Я думаю, что эти термины пересекаются. Например, протокол HTTP является синхронным, но реализация HTTP с использованием неблокирующего ввода-вывода может быть асинхронной. Опять же, неблокирующий вызов API, такой как read/write/try_lock, синхронен (он сразу дает ответ), но "обработка данных" асинхронна.

в асинхронном аппаратном обеспечении код просит некоторую сущность сделать что-то и может делать другие вещи, пока действие выполняется; как только действие завершено, сущность обычно сигнализирует код каким-то образом. Неблокирующая архитектура будет отмечать спонтанно возникающие действия, которые могут быть интересны коду, и позволит коду спросить, какие такие действия произошли, но код будет знать о таких действиях только тогда, когда он явно спрашивает о них. На основе событий архитектура утвердительно сообщить код, когда события происходят спонтанно.

рассмотрим последовательный порт, из которого код захочет получить 1000 байт.

в архитектуре блокирующего чтения код будет ждать, пока не поступит 1000 байт или он не решит отказаться.

в архитектуре асинхронного чтения код сообщит драйверу, что он хочет 1000 байт, и будет уведомлен, когда 1000 байт прибыли.

в неблокирующем режиме архитектура, код может спросить в любое время, сколько байтов прибыло, и может прочитать любые или все такие данные, когда он считает нужным, но единственный способ узнать, когда все данные прибыли,-это спросить; если код хочет узнать в течение четверти секунды, когда 1000-й байт прибыл, он должен проверять каждую четверть секунды или около того.

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

для меня неблокирующее означает, что выполнение действия в потоке не зависит от выполнения других потоков, оно, в частности, не требует критического раздела.

асинхронный означает, что exectuion происходит за пределами потока звонящего, и потенциально отложенных. Выполнение обычно происходит в другом потоке.

чтение параллельных данных не блокируется (нет необходимости блокировать), но синхронно. Наоборот, запись данных одновременно в a синхронный способ блокировки (требуется эксклюзивная блокировка). Способ сделать его неблокирующим с точки зрения основного потока-сделать записи асинхронными и отложить их выполнение.

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

эти три термина связаны, но для меня это разные понятия. Может быть, люди используют их несколько взаимозаменяемым образом.

Как правило, неблокирующая архитектура основана на вызовах методов, которые, хотя они могут выполняться в течение длительного времени на работник поток, не блокируйте вызов нить. Если вызывающему потоку необходимо получить информацию о задаче, которую выполняет рабочий поток, или из нее, это зависит от вызывающего потока.

архитектура на основе событий основана на концепции кода, выполняемого в ответ на события, которые запускаются. Синхронизация выполнение кода обычно не детерминировано, но события могут вызывать методы блокировки; просто потому, что система основана на событиях, не означает, что все, что она делает, не блокируется.

Как правило, асинхронная архитектура является основанной на событиях, неблокирующей архитектурой.

при выполнении асинхронного вызова обработчики событий регистрируются в API, предоставляющем службы синхронизации, чтобы уведомить вызывающего абонента о том, что то, что интересует вызывающего абонента, имеет получилось. Затем вызов немедленно возвращается (неблокирующее поведение), и вызывающий может продолжить выполнение. Когда события запускаются обратно в вызывающий процесс, они будут обрабатываться в некотором потоке в этом процессе.

важно понимать, будут ли события обрабатываться в одном потоке или нет, так как это повлияет на неблокирующий характер выполнения, но я лично не знаю о каких-либо библиотеках, которые выполняют асинхронное управление выполнением в одном потоке нитка.

Я удалил выше пункт, потому что это не совсем правильно, как указано. Мое намерение было сказать, что даже если операции в системе не блокируются, например, выполнение вызовов к объекту ОС и продолжение выполнения, характер однопоточного выполнения означает, что при запуске событий они будут конкурировать с другими задачами обработки для вычислительного времени в потоке.

Так что ответ на ваш первый и второй вопрос:

неблокирующее эффективно то же самое, что и асинхронное - вы делаете вызов, и вы получите результат позже, но пока это происходит, вы можете сделать что-то еще. Блокирование-это наоборот. Вы ждете звонка, чтобы вернуться, прежде чем продолжить свое путешествие.

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

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

в тот момент, когда ваш код запрашивает что-то, что займет некоторое время, чтобы ответить, ваша ОС знает, что она может заняться другими вещами. Ваш код - процесс, поток или эквивалент, блоки. Ваш код совершенно не обращает внимания на то, что еще происходит в ОС, пока он ждет этого сетевого подключения, или пока он ждет этого ответа от HTTP-запроса, или пока он ждет этого чтения/записи файла и так далее. Вы код может "просто" ждать щелчок мыши. То, что на самом деле происходило в это время, было то, что ваша ОС легко управляет, планирует и реагирует на "события" - вещи, которые ОС ищет, такие как управление памятью, ввод/вывод (клавиатура, мышь. диск, интернет), другие задачи, восстановление после сбоя и т. д.

операционные системы чертовски жесткие. Они действительно хорошо скрывают все сложные асинхронные / неблокирующие вещи от вас, программиста. И именно так большинство программистов попали туда, где мы находимся сегодня с программным обеспечением. Теперь мы поражаем ограничения процессора, люди говорят, что можно делать параллельно, чтобы улучшить производительность. Это означает, что асинхронная / неблокирующая блокировка кажется очень выгодной вещью, и да, если ваше программное обеспечение требует этого, я могу согласиться.

Если вы пишете внутренний веб-сервер, то действуйте с осторожностью. Помните, что вы можете масштабировать по горизонтали гораздо дешевле. Netflix / Amazon / Google / Facebook являются очевидными исключениями из этого правила, хотя, чисто потому, что это работает дешевле для них использовать меньше оборудования.

Я расскажу вам, почему асинхронный / неблокирующий код-это кошмар с внутренними системами....

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

2) трассировки стека в реактивном коде становятся неразборчивыми - трудно понять, что называется, что, когда, почему и как. Удачи с отладкой.

3) Вы должны больше думать о том, как вещи терпят неудачу, особенно когда многие вещи возвращаются из того, как вы их отправили. В старом мире вы делали одно дело за раз.

4) это труднее проверить.

5) это труднее поддерживать.

6) это больно. Программирование должно быть радостным и веселым. Только мазохисты любят боль. Люди, которые пишут параллельные/реактивные фреймворки, являются садистами.

и да, я написал как синхронизацию, так и асинхронность. Я предпочитаю синхронный, как 99,99 бэк-энда приложения могут справиться с этой парадигмой. Интерфейсные приложения нуждаются в реактивном коде, без вопросов, и это всегда было так.

  1. Да, код может быть асинхронным, неблокирующим и основанным на событиях.

  2. самое главное в программировании - убедиться, что ваш код работает и отвечает в приемлемое время. Придерживаться основных принципов и вы не ошибетесь.

Comments

    Ничего не найдено.