Erlang Language
processer
Sök…
Skapa processer
Vi skapar en ny samtidiga process genom att kalla spawn
funktionen. spawn
funktionen får som parameter en funktion Fun
att processen utvärderar. Returvärdet av spawn
funktion är den skapade processen identifieraren (pid).
1> Fun = fun() -> 2+2 end.
#Fun<erl_eval.20.52032458>
2> Pid = spawn(Fun).
<0.60.0>
Du kan också använda spawn/3
att starta en process som kommer att utföra en specifik funktion från en modul: spawn(Module, Function, Args)
.
Eller använd spawn/2
eller spawn/4
liknande sätt för att starta en process i en annan nod: spawn(Node, Fun)
eller spawn(Node, Module, Function, Args)
.
Meddelande vidarebefordras
Två erlanga processer kan kommunicera med varandra, vilket också kallas meddelandeförmedling .
Den här proceduren är asynkron i den form att sändningsprocessen inte kommer att stoppas efter att meddelandet har skickats.
Skicka meddelanden
Detta kan uppnås med konstruktionen Pid ! Message
, där Pid
är en giltig processidentifierare (pid) och Message
är ett värde av vilken datatyp som helst.
Varje process har en "postlåda" som innehåller de mottagna meddelandena i den mottagna ordern. Denna "brevlåda" kan tömmas med inbyggd flush/0
funktionen.
Om ett meddelande skickas till en icke-befintlig process kommer meddelandet att förkastas utan fel!
Ett exempel kan se ut som följande, där self/0
returnerar pid för den aktuella processen och pid/3
skapar en 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
Det är också möjligt att skicka ett meddelande till flera processer samtidigt med Pid3!Pid2!Pid1!Msg
.
Ta emot meddelanden
Mottagna meddelanden kan behandlas med receive
.
receive
Pattern1 -> exp11, .., exp1n1;
Pattern2 when Guard -> exp21, .., exp2n2;
...
Other -> exp31, .., exp3n3;
...
after Timeout -> exp41, .., exp4n4
end
Pattern
kommer att jämföras med meddelandena i "brevlådan" som börjar med det första och äldsta meddelandet.
Om ett mönster matchar, tas det matchade meddelandet bort från "brevlådan" och klausulkroppen utvärderas.
Det är också möjligt att definiera timeout med after
konstruktionen.
En Timeout
är antingen väntetiden i millisekunder eller atomens infinity
.
Returvärdet för receive
är det sista utvärderade klausulorganet.
Exempel (räknare)
En (väldigt) enkel räknare med meddelandeöverföring kan se ut i följande.
-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.
Interaktion med räknaren.
1> C0 = counter0:start().
<0.39.0>
2> C0!increment.
increment
3> C0!increment.
increment
Registrera processer
Det är möjligt att registrera en process (pid) till ett globalt alias.
Detta kan uppnås med den inbyggda register(Alias, Pid)
, där Alias
är atomen för att få åtkomst till processen och Pid
är process-id.
Aliaset kommer att vara globalt tillgängligt!
Det är väldigt lätt att skapa delat tillstånd, vilket vanligtvis inte är att föredra. ( Se även här )
Det är möjligt att avregistrera en process med unregister(Pid)
och ta emot pid från ett alias med whereis(Alias)
.
Använd registered()
för en lista över alla registrerade alias.
Exemplet registrerar Atom foo till pid för den aktuella processen och skickar ett meddelande med hjälp av det registrerade Atom.
1> register(foo, self()).
true
2> foo ! 'hello world'.
'hello world'