Синхронные и асинхронные языки

Последний год я работал над Java и flex. При написании гибкого кода большинство частей моего кода выбрасывались из-за его асинхронности. Это заставило меня задуматься о реальных преимуществах и недостатках синхронных исполняемых языков по сравнению с асинхронными.

В каких областях они сильнее по сравнению с другими и в каких областях они падают?


person Umesh    schedule 18.12.2009    source источник
comment
Как язык может быть асинхронным?   -  person Azeem.Butt    schedule 18.12.2009
comment
@NSD - он имеет в виду, что flex никогда не блокируется - все операции, которые могут блокироваться на других платформах, выполняются асинхронно.   -  person Grokys    schedule 18.12.2009
comment
У вас есть определение синхронного исполняемого языка? Или вы просто интерпретируете управляемую событиями природу Flex (которая также встречается почти во всех других GUI API, включая Java) как асинхронную?   -  person kdgregory    schedule 18.12.2009
comment
@kdgregory- я не могу понять, почему вы просто изменили механизм выполнения flex, назвав характер flex, управляемый событиями. Мне довольно сложно это переварить, так как это первый язык, с которым я играю, который имеет такое поведение. Другие языки, такие как c и все, будут ждать завершения вызываемого метода, чтобы перейти к следующей строке. Но в этом нет. Но flex выполняет их в потоках, что ускоряет выполнение (я думаю). Но у них также есть прослушиватели событий, которым нужно, чтобы прослушиватель продолжал работать, что поглощает циклы ЦП. Я прав? Итак, в чем преимущество?   -  person Umesh    schedule 18.12.2009
comment
Я не думал, что Flex — это язык. Я предполагаю, что это области, в которые я падаю.   -  person Azeem.Butt    schedule 18.12.2009
comment
C может иметь асинхронные методы, как и большинство языков. Может вы путаете языки с фреймворками?   -  person Peter Recore    schedule 19.12.2009
comment
@Azeem.Butt Странный пример, javascript. Принудительный асинхронный стиль с помощью «одного потока»   -  person ceram1    schedule 01.01.2015


Ответы (3)


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

Короче говоря, как указывали другие люди, реальная сила асинхронной модели заключается в ее способности создавать надежные системы, которые хорошо взаимодействуют с реальным миром. Никто не мог бы реально использовать приложение Silverlight (или Flash), если поток пользовательского интерфейса останавливался каждый раз, когда для возврата вызова веб-службы требовалось несколько секунд.

Самым большим недостатком является то, что полученный код сложен и его трудно устранять. Такие вещи, как обработка ошибок, — это PITA, но самое раздражающее, с чем мне приходилось сталкиваться, — это координировать ответы от нескольких асинхронных вызовов. Если, скажем, вам нужна информация от звонка А перед выполнением звонка Б, и вам нужна информация от звонка Б до выполнения звонка С (и т. д.), результирующий код выглядит очень неприятно и восприимчив к всевозможным странным побочным эффектам. . Существуют методы, позволяющие заставить все это работать и даже достаточно чисто, но если вы пришли из синхронного мира (как и я), это требует значительного обучения. (И не помогает то, что Microsoft продвигает события как способ работы с вызовами WCF, когда обратные вызовы, на мой взгляд, намного чище и менее подвержены странным побочным эффектам, о которых я говорил.)

(И да, другие люди правы, говоря, что асинхронным является не столько язык, сколько конкретные фреймворки требуют построения вашего кода асинхронным образом, но я понимаю, что вы имеете в виду.)

Обновление 2014.09.23 -

Я проделал гораздо больше работы с различными асинхронными фреймворками с тех пор, как написал ответ выше (как, вероятно, и все остальные, кто занимался веб-кодированием), и подумал, что добавлю несколько дополнительных случайных заметок:

  • Если вы используете такие языки, как C# или F#, которые имеют первоклассную асинхронную поддержку, многое становится намного проще, по крайней мере, когда вы обдумываете странные шаблоны async/await. Возможность легко зацикливаться на асинхронных вызовах и обернуть все это простым try/catch — это потрясающе, если вам когда-либо приходилось делать это по-старому.

  • Если вы не используете язык с первоклассной поддержкой асинхронности, начните использовать любую поддержку promise, future или task, которую предоставляет язык (например, $.Deferred() в JQuery или $q.defer() в Angular. Они намного чище и обеспечивают лучшую структуру, чем то, что вы обычно получаете с обратными вызовами.

  • Асинхронный код имеет решающее значение для написания масштабируемых серверных систем. Одна из самых больших проблем с хорошим масштабированием типичного веб-сервера заключается в том, что у него начинают заканчиваться потоки, по крайней мере, если он выделяет поток для достижения входящего запроса. Если этот поток останавливается из-за ожидания завершения продолжительного синхронного вызова, он совершенно не может помочь с чем-либо еще. Гораздо лучше сделать код вашего веб-сервера асинхронным, чтобы, когда вы ожидаете возврата вызова БД, этот поток мог обслуживать полдюжины других запросов, пока БД работает и делает все, что делает БД. На данный момент для хорошо масштабируемых систем асинхронность — единственная игра в городе. (Просто спросите любого поклонника Node.)

person Ken Smith    schedule 18.12.2009
comment
Существуют ли какие-либо методы написания приложений в среде, управляемой событиями? - person Umesh; 18.12.2009
comment
Скажем так, лямбда-выражения — ваш новый лучший друг :-). Кроме того, я думаю, что шаблоны и практики будут сильно различаться от фреймворка к фреймворку, в зависимости от ограничений, которые они на вас накладывают. Например, в мире Silverlight я обнаружил, что очень помогает обернуть управляемый событиями шаблон, который предоставляет Microsoft, шаблоном, ориентированным на обратный вызов (и я обычно реализую обратный вызов в виде лямбда-выражения). Это значительно упрощает отслеживание логики приложения. Я не сделал достаточно Flex, чтобы знать, что там уместно. - person Ken Smith; 19.12.2009
comment
Большое спасибо за ваше объяснение, сэр. Я также пришел из мира синхронизации и постоянно думал, насколько грязный асинхронный код. Я воспользуюсь вашим советом и займусь Node. Спасибо! - person Capitan Empanada; 11.07.2020

(Оставляя в стороне обсуждение уровня семантики, т.е. «синхронный/асинхронный язык»)

«Структура», построенная на «языке» (каким бы он ни был), должна быть в состоянии обрабатывать такие случаи (синхронный/асинхронный поток программы), чтобы быть полезной (читай: $ мудрой).

Асинхронные идиомы подходят для любого масштаба.

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

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

person jldupont    schedule 18.12.2009
comment
Верно, если вы думаете о нескольких тестовых примерах параллельно. Но, насколько я понимаю, они помогут только для тестовых случаев. В реальной жизни и во всем последующем то, что происходит, зависит исключительно от того, что происходит сейчас или в результате этого. Так как же асинхронность может стать достижением? - person Umesh; 18.12.2009
comment
@Umesh: то, что происходит сейчас, - это песочница, созданная событиями искусственной сериализации. Это вопрос системы отсчета (как мы назвали бы это в физике). Что касается того, как асинхронность может стать достижением, я должен сказать, что не понимаю вас. Не могли бы вы объяснить? - person jldupont; 18.12.2009
comment
Ваше объяснение прояснило меня. Пожалуйста, забудьте мой вопрос. Спасибо - person Umesh; 18.12.2009
comment
@Umesh: Вы действительно хотите, чтобы строки меню в вашем веб-браузере не отвечали всякий раз, когда ваш браузер отправляет сетевой запрос? Есть много мест, где что-то может произойти, не зная результата какого-то случайного вызова. - person tloach; 18.12.2009
comment
@tloach - согласен. Но просто мысль... асинхронный подход решает вопрос, который вы задали. Но для достижения функциональности, которая должна быть синхронной, мы делаем события и все на асинхронном языке (скрипт flex/action). Поэтому мой вопрос для jidupont заключался в том, какова частота возникновения синхронных событий по сравнению с асинхронными событиями. Означает, в каком методе должен быть основан язык программирования, и указать другой в качестве опции, которую вы можете реализовать с его помощью. (Я думаю, что я ясно) - person Umesh; 18.12.2009

Я думаю дело не в языке, а во фреймворке.

Контр-пример:

При написании приложений «Классический Mac» (MacOS 9 и более ранние версии) на C («синхронный» язык, если он когда-либо существовал), у вас нет вытесняющей многопоточности, поэтому все потенциально блокирующие системные вызовы имеют асинхронный аналог, где вы заполняете блок данных с параметрами, включая функцию обратного вызова. Затем вы выполняете системный вызов (который будет немедленно возвращен), и ваш обратный вызов будет вызываться асинхронно (на так называемом «уровне прерывания»). Нередко обратный вызов выполнял другой асинхронный системный вызов, создавая длинный фоновый поток, который выполнялся асинхронно с основным.

person Javier    schedule 18.12.2009
comment
Действительно ли это означает улучшение производительности за счет параллельной работы и использования аппаратного обеспечения? Но какова стоимость прослушивания обратных вызовов из родительского потока. У них есть лучшая сторона? - person Umesh; 18.12.2009
comment
@Umesh: вы не прослушиваете обратные вызовы из другого потока, поток вызывает обратный вызов напрямую. Накладные расходы такие же, как и при вызове любой другой функции. - person tloach; 18.12.2009