Блокировка каналов против асинхронного сообщения передач

StackOverflow https://stackoverflow.com/questions/2239731

Вопрос

Я заметил два метода для «передачи сообщений». Один из которых я видел, что Эрланг использовал, а другой - от Python. Из того, что я понимаю, вот разница

Стиль Erlang - сообщения отправляются и очереди в почтовом ящике процесса получения. Оттуда они удалены на основе FIFO. После того, как первый процесс отправляет сообщение, он может продолжаться.

Стиль Python - обрабатывайте очереди на отправку в процесс B. B в настоящее время выполняет какое -то другое действие, поэтому A заморожен, пока B не будет готов к приему. Как только B открывает канал чтения, A отправляет данные, затем они оба продолжаются.

Теперь я вижу плюсы метода Эрлана, заключающиеся в том, что у вас нет заблокированных процессов. Если B никогда не может получить, A может продолжаться. Однако я заметил в некоторых программах, которые я написал, что ящики Erlang могут наполнить сотни (или тысячи) сообщений, поскольку приток сообщений больше, чем отток.

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

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

Это было полезно?

Решение

Мой опыт в программировании Erlang заключается в том, что, когда вы ожидаете высокой скорости обмена сообщениями (то есть более быстрым производителем, чем потребитель), вы добавляете свой собственный контроль потока. Простой сценарий

  • Потребитель будет: отправить сообщение, дождитесь ACK, затем повторите.
  • Производитель будет: подождите сообщения, отправьте ACK при получении и обработке сообщения, затем повторите.

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

Эти подходы и другие управления потоком могут быть скрыты за функциями, первый в основном уже доступен в gen_server:call/2,3 против а gen_server ОТП процесс поведения.

Я вижу асинхронные сообщения, как в Эрланге, как лучший подход, поскольку, когда задержки высоки, вы можете очень хотеть избежать синхронизации при обмене сообщениями между компьютерами. Затем можно составить умные способы реализации управления потоком. Скажите, требуя ACK от потребителя для каждого N сообщений, которые производитель отправил его, или отправляйте специальное «пинг меня, когда вы получили это одно» сообщение время от времени, чтобы подсчитать время пинга.

Другие советы

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

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

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

Что лучше? Это трудно сказать. Здесь нет простых ответов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top