Асинхронное программирование - это гораздо больше философии, чем просто очередной трюк программирования. В то время как на ваш последний вопрос были получены ответы, главным образом о аспектах программирования, и мой ответ был отстраненным от того, что я был в основном теоретическим, я пытаюсь дать вам свежую перспективу, основанную на той же строке, но объяснения, а не просто ссылки.
В этом рассказывается о некоторых принципах асинхронного программирования.
Предположим, вы идете в пекарню (и предположим, что торт будет приготовлен после заказа) - у вас есть два варианта: либо вы подождете, пока торт будет готов, либо вы отдадите заказ и отправитесь обратно домой и заберете позже, когда он будет готов. Первый (ожидание) является синхронным методом, а позже - асинхронным методом . Само собой разумеется, что этот пример дает хорошую справку, почему вы должны использовать асинхронные методы вместо синхронных.
Программирование на основе событий - это только один из способов построения асинхронных систем, и это не просто полезный шаблон проектирования, а скорее архитектурный шаблон. Я перечисляю случаи, когда эта теория используется практически полезным способом - в надежде, что она внесет некоторую ясность
Одним из первых примеров асинхронных систем является система ввода-вывода Unix. Хотя мы знаем read()
, write()
и даже select()
вызываем блокировку потока программы, но внутри ОС они асинхронны, то есть ядро обычно знает, что блочному устройству (так называемому жесткому диску) потребуется некоторое время для заполнения буфера, пока такое время ЦП не освободится из этой соответствующей нити и, следовательно, нить припаркована как (не готова). См. 1. Морис Бах "Дизайн операционной системы Unix"
Другим наиболее распространенным примером является большинство структур пользовательского интерфейса. Здесь все пользовательские клики сначала отправляются через контроллер, который, в свою очередь, вызывает соответствующее приложение. Важно то, что такие обратные вызовы не должны заставлять обратные вызовы ждать, иначе система зависнет. Обратный вызов от контроллера пользовательского интерфейса к бэкэндам обычно асинхронный, если они связаны с интенсивной обработкой.
Другим хорошим примером асинхронного программирования (в виде чистого шаблона проектирования) является Active Object. Активный объект - это объект, который имеет свой собственный частный поток, так что можно хранить много запросов в очереди и выполнять их по одному. См. Этот документ: активный объект . Этот шаблон интенсивно используется как для корпоративного программного обеспечения, так и для мобильных платформ. Популярные платформы Java / EJB и .NET допускают локальный или удаленный вызов асинхронного метода, который по существу позволяет обычным объектам становиться активными объектами. Активные объекты были представлены в Symbian: Активные объекты в Symbian OS от Aapo Haapanen (см. Также: Активные объекты в Symbian ). Это теперь также присутствует вAndroid ).
Помимо Активного объекта, тот же автор Дуглас С. Шмидт создал ряд других работ, которые являются другими параллелями Активному объекту и также являются асинхронными шаблонами. См. Этот раздел «Шаблоны обработки событий», и полный отчет об этом доступен в его книге « Архитектура программного обеспечения на основе шаблонов: шаблоны для параллельных и сетевых объектов» - V2
Когда данные потребности объекта для возврата API, в то время как работают в фоновом режиме , чтобы реально выполнить работу, обычная методика должна иметь систему многопоточную для достижения этой цели. Потоковые системы присутствуют повсюду: от C (posix), C ++ ( boost ) до Java, C # и так далее. Активный объект - это всего лишь абстракция, которая может это скрыть. Узнайте, почему реализации активных объектов предпочтительнее, чем голые потоки. Еще одно хорошее чтение .
Но эта концепция выходит за пределы потоков или объектов внутри приложения и становится асинхронной. Одно из лучших применений - в распределенных системах, где двум приложениям не обязательно ждать друг друга для координации. Старый добрый (или не очень хороший, как ни крути) RPC был синхронным. [конечно, есть и другие асинхронные RPC ]. Но современные альтернативы, такие как Message Oriented Middleware , по вполне понятным причинам действительно асинхронны.
Последнее, но наиболее интересное, - это программирование агентов, которое может использовать асинхронную модель коммуникации .
Хотя асинхронное программирование выглядит привлекательно, оно создает свою собственную сложность, включая:
- рамки для передачи возвращаемого значения
- дополнительные накладные расходы на связь
- дополнительная потребность в синхронизации конструкций
- возможность тупиков, гонок и т. д., если все сделано неправильно.
... и так далее.
Он всегда должен использоваться только по подлинным причинам.
Так когда же следует использовать асинхронную модель? Когда следует поместить фоновый поток и разрешить вызывающей стороне работать асинхронно? Вот несколько хороших правил большого пальца, когда они применяются (но не завершены)
Когда система хочет применить строгий серьезный диалог ресурсов: например, вы хотите сохранить абсолютное фиксированное количество потоков. Асинхронный шаблон заставляет систему реализовать очередь.
Когда звонящему нужно делать «другие полезные вещи», это действительно так. Очень часто другой поток, даже если он разблокирован, не будет делать ничего полезного и будет зависать от результатов опроса. Это действительно может потреблять больше ресурсов процессора, чем базовая синхронная модель.
Когда вам нужны более высокие уровни надежности в распределенных системах. (см. Посредственно ориентированное промежуточное ПО )