В каком порядке процесс Erlang потребляет сообщения? - PullRequest
7 голосов
/ 28 июля 2011

Обрабатываются ли сообщения в порядке поступления, или они сортируются по меткам времени или что-то в этом роде?

Ответы [ 3 ]

12 голосов
/ 28 июля 2011

Порядок сообщений сохраняется между процессом и другим. Чтение из FAQ :

10,9 Гарантирован ли порядок приема сообщений?

Да, но только в рамках одного процесса.

Если есть живой процесс, и вы отправляете ему сообщение А, а затем сообщение B, гарантируется, что если сообщение B прибыло, сообщение A прибыло раньше это.

С другой стороны, представьте себе процессы P, Q и R. P отправляет сообщение A Q, а затем сообщение B к R. Нет гарантии, что A прибудет до Б. (Распределенному Эрлангу было бы довольно тяжело, если бы это был необходим!)

@ Кнутин прав в том, как вы можете использовать сообщения в процессе. Кроме того, обратите внимание, что вы можете использовать два последующих оператора получения, чтобы гарантировать, что определенное сообщение будет использовано после другого:

receive
  first ->
    do_first()
end,
receive
  second ->
    do_second()
end

Оператор получения блокируется. Это гарантирует, что вы никогда не будете do_second() перед вами do_first(). Отличие от второго решения @ knutin заключается в том, что в этом случае, если что-то не важный приходит непосредственно перед важным , вы ставите в очередь важный бит.

4 голосов
/ 28 июля 2011

Почтовый ящик всегда сохраняется в порядке поступления сообщений.

Однако порядок использования сообщений определяется вашим кодом.

Если у вас есть простой процесс с общим предложением receive, который получает что-либо, порядок получения сообщений совпадает с порядком их поступления.

loop() ->
   receive
        Any ->
            do_something(Any),
            loop()
   end.

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

loop() ->
    receive
        {important, Stuff} ->
            do_something_important(Stuff),
            loop();
        Any ->
            do_something(Any)
            loop()
     end.
1 голос
/ 28 июля 2011

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

Эта проблема действительно показывает свое наихудшее, когда у вас есть, например, модуль поведения gen_server, потому что в этом случае, при всегда одинаковой схеме сопоставления с образцом, сообщения, не входящие в область действия, будут заполнять очередь сообщений, если вы не определите (некрасиво) и подвержен ошибкам, ИМХО) шаблон соответствия всем, как:

receive
    ... -> ...;
    ... -> ...;
    MatchAllPatterns -> ok.
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...