Процессор почтовых ящиков в распределенных системах - PullRequest
17 голосов
/ 02 февраля 2009

Я заметил следующий комментарий в моей копии Expert F # на странице 379:

Передача и обработка сообщений

Часто проводится различие между параллельный доступ к общей памяти и сообщение проходящий параллелизм . Бывший часто более эффективный на локальных машинах и рассматривается в разделе «Использование Параллелизм совместно используемой памяти "позже в эта глава. Последний масштабируется до системы, где нет общего память, например, распределена системы, а также могут быть использованы, чтобы избежать проблемы с производительностью, связанные с разделяемая память.

Мне интересен параллелизм передачи сообщений между процессами без разделяемой памяти. Все примеры в Expert F # и в Интернете, которые демонстрируют, как использовать MailboxProcessor, содержат некоторые варианты этого кода:

let counter =
    MailboxProcessor.Start(fun inbox ->
        let rec loop n =
            async {
                do printfn "n = %d, waiting... " n
                let! msg = inbox.Receive()
                match msg with
                    | -1 ->
                        do printfn "'Til the bitter end..."
                        return ()
                    | n -> return! loop(n + msg)
            }
        loop 0)

counter.Post(20)
counter.Post(50)
counter.Post(-1) // kill mailbox

Другими словами, вы должны иметь дескриптор вашего MailboxProcessor в разделяемой памяти, прежде чем вы сможете отправлять сообщения на его канал. Насколько я знаю, это не параллелизм в стиле Erlang, поскольку вы можете отправлять сообщения в MailboxProcessors только в одном процессе (примечание: процесс, а не поток).

Возможно ли, чтобы один MailboxProcessor в одном процессе отправлял сообщения другому процессу MailboxProcessor? Если да, не могли бы вы предоставить образец?

Ответы [ 3 ]

8 голосов
/ 21 июля 2010

MailboxProcessor и AsyncReplyChannel не обеспечивают такую ​​же прозрачность расположения, как операция «pid bang» (Pid!) В Erlang. Конечно, это работает только тогда, когда распределенные узлы Erlang настроены правильно, то есть имена, DNS, синхронизированные модули, файлы cookie и т. Д. В OTP есть некоторые функции, которые упрощают администрирование. Конечно, если процессы Erlang находятся на одном узле, это просто работает. Но есть некоторые морщины с распределенным Erlang.

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

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

В конце концов, распределенные коммуникации никогда не были такими простыми. Мы могли бы реализовать AsynchWorker в F #, чтобы действовать в качестве нашего прокси и взаимодействовать с ним через AsynchReplyChannel.Send. Нам по-прежнему приходится думать об ошибках распределенных вычислений.

Наконец, параллелизм в стиле передачи сообщений не предполагает внепроцессного взаимодействия. Это подразумевает, что не существует общего состояния для управления с помощью блокировок, таким образом, более простая, менее подверженная ошибкам модель параллельных вычислений. Я думаю, что Сито с простыми числами является отличным примером этого стиля параллелизма. Пример F # не так эстетичен, как реализация Squeak или Erlang, из-за отсутствия встроенного синтаксиса для передачи сообщений, но он работает.

8 голосов
/ 02 февраля 2009

Я думаю, что вас немного смутила терминология. Процессы Эрланга не обязательно соответствуют непосредственно процессам ОС. У данного процесса ОС может быть несколько процессов Erlang (и обычно они есть), так же как у вашего процесса есть несколько потоков. Если вы хотите установить связь между несколькими процессами ОС, вы можете проверить System.Runtime.Remoting.Channels.Ipc . Предположительно, оболочка в стиле MailboxProcessor может быть создана вокруг этих API.

1 голос
/ 08 февраля 2011

Возможно, это будет делать

Карта Уменьшить с помощью агентов F #

Я не получил много отзывов, поэтому не уверен, что это на 100% правильно. Если вы думаете, что это плохо, пожалуйста, дайте мне знать.

Спасибо!

...