блокировка каналов и асинхронная передача сообщений - PullRequest
9 голосов
/ 10 февраля 2010

Я заметил два метода "передачи сообщений". Один я видел использование Erlang, а другой из Stackless Python. Из того, что я понимаю, вот в чем разница

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

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

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

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

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

Ответы [ 2 ]

7 голосов
/ 11 февраля 2010

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

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

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

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

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

4 голосов
/ 10 февраля 2010

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

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

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

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

...