Поиск…


Создание процессов

Мы создаем новый параллельный процесс, вызывая функцию spawn . Функция spawn получит в качестве параметра функцию Fun которую процесс будет оценивать. Возвращаемое значение функции spawn - это созданный идентификатор процесса (pid).

1> Fun = fun() -> 2+2 end.
#Fun<erl_eval.20.52032458>
2> Pid = spawn(Fun).
<0.60.0>

Вы также можете использовать spawn/3 для запуска процесса, который будет выполнять определенную функцию из модуля: spawn(Module, Function, Args) .
Или используйте spawn/2 или spawn/4 аналогично, чтобы запустить процесс в другом узле: spawn(Node, Fun) или spawn(Node, Module, Function, Args) .

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

Два процесса erlang могут взаимодействовать друг с другом, что также известно как передача сообщений .
Эта процедура является асинхронной в том виде, в котором процесс отправки не будет остановлен после отправки сообщения.

Отправка сообщений

Это может быть достигнуто с помощью конструкции Pid ! Message , где Pid является допустимым идентификатором процесса (pid), а Message - значением любого типа данных.

Каждый процесс имеет «почтовый ящик», который содержит полученные сообщения в полученном порядке. Этот «почтовый ящик» может быть опустошен с помощью встроенной функции flush/0 .

Если сообщение отправляется в не существующий процесс, сообщение будет отброшено без каких-либо ошибок!

Пример может выглядеть следующим образом: self/0 возвращает pid текущего процесса, а pid/3 создает pid.

1> Pidsh = self().
<0.32.0>
2> Pidsh ! hello.
hello
3> flush().
Shell got hello
ok
4> <0.32.0> ! hello.
* 1: syntax error before: ’<’
5> Pidsh2 = pid(0,32,0).
<0.32.0>
6> Pidsh2 ! hello2.
hello2
7> flush().
Shell got hello2
ok

Также можно отправить сообщение нескольким процессам сразу, с Pid3!Pid2!Pid1!Msg .

Получение сообщений

Полученные сообщения могут обрабатываться с помощью конструкции receive .

receive
  Pattern1            -> exp11, .., exp1n1;
  Pattern2 when Guard -> exp21, .., exp2n2;
  ...
  Other               -> exp31, .., exp3n3;
  ...
  after Timeout       -> exp41, .., exp4n4
end

Pattern будет сравниваться с сообщениями в «почтовом ящике», начиная с первого и самого старого сообщений.
Если шаблон совпадает, совпадающее сообщение удаляется из «почтового ящика» и вычисляется тело предложения.

Также можно определить тайм-ауты с after конструкцией.
Timeout - это либо время ожидания в миллисекундах, либо infinity атома.

Возвращаемое значение receive - это последний обработанный объект предложения.

Пример (счетчик)

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

-module(counter0).
-export([start/0,loop/1]).

% Creating the counter process.
start() ->
    spawn(counter0, loop, [0]).

% The counter loop.
loop(Val) ->
    receive
        increment ->
           loop(Val + 1)
    end.

Взаимодействие с прилавком.

1> C0 = counter0:start().
<0.39.0>
2> C0!increment.
increment
3> C0!increment.
increment

Регистрация процессов

Можно зарегистрировать процесс (pid) для глобального псевдонима.
Это может быть достигнуто с помощью функции создания в register(Alias, Pid) , где Alias является атомом для доступа к процессу, а Pid - идентификатором процесса.

Псевдоним будет доступен по всему миру!
Очень просто создать общее состояние, которое обычно не является предпочтительным. ( См. Также здесь )

Можно отменить регистрацию процесса с unregister(Pid) и получить pid из псевдонима whereis(Alias) .

Используйте registered() список всех зарегистрированных псевдонимов.

Пример регистрирует Atom foo для pid текущего процесса и отправляет сообщение с использованием зарегистрированного Atom.

1> register(foo, self()).
true
2> foo ! 'hello world'.
'hello world'


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow