Szukaj…


Tworzenie procesów

Tworzymy nowy równoległy proces, wywołując funkcję spawn . Funkcja spawn otrzyma jako parametr funkcję Fun którą proces oceni. Zwracana wartość funkcji spawn to utworzony identyfikator procesu (pid).

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

Możesz także użyć spawn/3 aby uruchomić proces, który wykona określoną funkcję z modułu: spawn(Module, Function, Args) .
Lub użyj spawn/2 lub spawn/4 podobnie, aby rozpocząć proces w innym węźle: spawn(Node, Fun) lub spawn(Node, Module, Function, Args) .

Przekazywanie wiadomości

Dwa procesy erlang mogą się ze sobą komunikować, co jest również znane jako przekazywanie wiadomości .
Ta procedura jest asynchroniczna , ponieważ proces wysyłania nie zostanie zatrzymany po wysłaniu wiadomości.

Wysyłanie wiadomości

Można to osiągnąć za pomocą konstruktu Pid ! Message , w którym Pid jest prawidłowym identyfikatorem procesu (pid), a Message jest wartością dowolnego typu danych.

Każdy proces ma „skrzynkę pocztową”, która zawiera odebrane wiadomości w otrzymanej kolejności. Tę „skrzynkę pocztową” można opróżnić za pomocą flush/0 funkcji flush/0 .

Jeśli wiadomość zostanie wysłana do nieistniejącego procesu, wiadomość zostanie odrzucona bez żadnego błędu!

Przykład może wyglądać następująco: self/0 zwraca pid bieżącego procesu, a pid/3 tworzy 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

Możliwe jest również wysłanie wiadomości do wielu procesów jednocześnie, za pomocą Pid3!Pid2!Pid1!Msg .

Odbieranie wiadomości

Otrzymane wiadomości mogą być przetwarzane za pomocą konstrukcji receive .

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

Pattern zostanie porównany z wiadomościami w „skrzynce pocztowej”, zaczynając od pierwszej i najstarszej wiadomości.
Jeśli wzorzec jest zgodny, dopasowana wiadomość jest usuwana z „skrzynki pocztowej” i analizowana jest treść klauzuli.

Możliwe jest również zdefiniowanie limitów czasu za pomocą konstrukcji after .
Timeout to czas oczekiwania w milisekundach lub infinity atomu.

Zwracana wartość parametru receive jest ostatnią ocenioną treścią klauzuli.

Przykład (licznik)

(Bardzo) prosty licznik z przekazywaniem wiadomości może wyglądać następująco.

-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.

Interakcja z kontuarem.

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

Zarejestruj procesy

Możliwe jest zarejestrowanie procesu (pid) w globalnym aliasie.
Można to osiągnąć za pomocą funkcji wbudowanego register(Alias, Pid) , w której Alias jest atomem umożliwiającym dostęp do procesu, a Pid jest identyfikatorem procesu.

Alias będzie dostępny na całym świecie!
Bardzo łatwo jest utworzyć stan współdzielony, co zwykle nie jest preferowane. ( Zobacz także tutaj )

Możliwe jest wyrejestrowanie procesu z unregister(Pid) i otrzymanie pid z aliasu z whereis(Alias) .

Użyj registered() aby wyświetlić listę wszystkich zarejestrowanych aliasów.

Przykład rejestruje atom Foo na pid bieżącego procesu i wysyła komunikat za pomocą zarejestrowanego atomu.

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


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow