English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
A programação concorrente no Erlang deve seguir os seguintes princípios básicos ou processos.
A lista inclui os seguintes princípios:
piD = spawn(Fun)
Cria um novo processo concorrente para avaliar a Fun. O novo processo roda paralelamente ao chamador. Um exemplo a seguir-
-module(helloworld). -export([start/0]). start() -> spawn(fun()) -server("Hello") end). server(Message) -> io:fwrite("~p", [Message]).
The output of the above program is-
"Hello"
Enviar mensagens para o processo usando o identificador Pid. A envio de mensagens é assíncrono. O remetente não espera, mas continua o que estava fazendo. "!" é chamado de operador de envio.
Um exemplo a seguir-
-module(helloworld). -export([start/0]). start() -> Pid = spawn(fun() -server("Hello") end), Pid ! {hello}. server(Message) -> io:fwrite("~p", [Message]).
Receive messages sent to the process. It has the following syntax-
receive Pattern1 [when Guard1] -> Expressions1; Pattern2 [when Guard2] -> Expressions2; ... End
When a message arrives at the process, the system tries to match it with Pattern1 1“). If successful1Evaluation. If the first pattern does not match, try using Pattern2and so on. If no pattern matches, save the message for future processing, and then the process waits for the next message.
The following program shows the use of all3An example of the entire process of issuing commands.
-module(helloworld). -export([loop/0, start/0]). loop() -> receive {rectangle, Width, Ht} -> io:fwrite("Area of rectangle is ~p~n", [Width * Ht]), loop(); {circle, R} -> io:fwrite("Area of circle is ~p~n", [3.14159 * R * R]), loop(); Other -> io:fwrite("Unknown"), loop() end. start() -> Pid = spawn(fun() -> loop() end), Pid ! {rectangle, 6, 10}.
The following points should be noted about the above program:
The loop function has a receiving end loop. Therefore, when a message is sent, it will be processed by the receiving end loop.
Generate a new process that will go to the loop function.
Messages are sent to the generated process using the Pid! message command.
The output of the above program is-
Area of the Rectangle is 60
Concurrently, it is important to determine the maximum number of processes allowed on the system. Then, you should be able to understand how many processes can be executed simultaneously on the system.
Let's see an example of how to determine the maximum number of processes that can be executed on the system.
-module(helloworld). -export([max/1,start/0]). max(N) -> Max = erlang:system_info(process_limit), io:format("Maximum allowed processes:~p~n", [Max]), statistics(runtime), statistics(wall_clock), L = for(1, N, fun() -> spawn(fun() -> wait() end) end), {_, Time1} = statistics(runtime), {_, Time2} = statistics(wall_clock), lists:foreach(fun(Pid) -> Pid ! die end, L), U1 = Time1 * 1000 / N, U2 = Time2 * 1000 / N, io:format("Process spawn time=~p (~p) microsegundos~n", [U1, U2]). wait() -> receive die -> void end. for(N, N, F) -> [F()]; for(I, N, F) -> [F()|for(I+1, N, F)]. start()-> max(1000), max(100000).
Em qualquer máquina com boa capacidade de processamento, as duas funções máximas acima passarão. A seguir está um exemplo de saída do programa acima.
Máximo permitido de processos:262144 Process spawn time=47.0 (16.0) microsegundos Máximo permitido de processos:262144 Process spawn time=12.81 (10.15) microsegundos
Às vezes, a sentença receive pode esperar eternamente por uma mensagem que nunca aparecerá. Isso pode ter muitos motivos. Por exemplo, pode haver erros lógicos em nosso programa ou o processo que deve nos enviar a mensagem pode ter falhado antes de enviar a mensagem.
A seguir está a sintaxe especificada para receber mensagens com timeout.
receive Pattern1 [when Guard1] -> Expressions1; Pattern2 [when Guard2] -> Expressions2; ... after Time -> Expressions end
O exemplo mais simples é criar uma função sleeper, conforme o programa a seguir.
-module(helloworld). -export([sleep/1,start/0]). sleep(T) -> receive after T -> true end. start()-> sleep(1000).
O código acima dormirá antes de realmente sair1000 milissegundos.
Cada processo no Erlang tem um correio associado. Quando você envia uma mensagem para esse processo, a mensagem é colocada no correio. Apenas quando a avaliação da sentença de recebimento é feita pelo programa, é verificado esse correio.
A seguir está a sintaxe geral da sentença de recebimento seletivo.
receive Pattern1 [when Guard1] -> Expressions1; Pattern2 [when Guard1] -> Expressions1; ... after Time -> ExpressionTimeout end
Isso é a maneira como a sentença de recebimento mencionada acima funciona-
Quando introduzimos uma sentença receive, iniciamos um temporizador (mas apenas se a expressão contiver uma seção after).
com o primeiro e-mail na caixa de entrada e tentar combiná-lo com o Padrão1,Padrão2Esperando correspondência. Se a correspondência for bem-sucedida, a mensagem será removida da caixa de entrada e avaliada a expressão após o padrão.
Se nenhum padrão na sentença receive correspondente à primeira mensagem na caixa de entrada, remova a primeira mensagem da caixa de entrada e coloque-a na 'Fila de Salvamento'. Em seguida, tente a segunda mensagem na caixa de entrada. Repita este processo até encontrar uma mensagem correspondente ou verificar todas as mensagens na caixa de entrada.
Se todas as mensagens na caixa de entrada não correspondem, o processo será suspenso e reprogramado para a próxima vez que uma nova mensagem for colocada na caixa de entrada. Observe que, quando uma nova mensagem é recebida, as mensagens na fila de salvamento não serão reencontradas; apenas a mensagem nova será correspondida.
Assim que uma mensagem for correspondida, todas as mensagens colocadas na fila de salvamento serão reintroduzidas na caixa de entrada na ordem do processo de chegada. Se foi configurado um temporizador, remova-o.
Se o temporizador já passou enquanto estava aguardando uma mensagem, avalie a expressão ExpressionsTimeout e coloque todas as mensagens salvas de volta na caixa de entrada na ordem do processo de chegada.