Erlang-동시성
Erlang의 동시 프로그래밍에는 다음과 같은 기본 원칙 또는 프로세스가 있어야합니다.
목록에는 다음 원칙이 포함됩니다.
piD = spawn (재미 있음)
Fun을 평가하는 새로운 동시 프로세스를 만듭니다. 새 프로세스는 호출자와 병렬로 실행됩니다. 예는 다음과 같습니다-
예
-module(helloworld).
-export([start/0]).
start() ->
spawn(fun() -> server("Hello") end).
server(Message) ->
io:fwrite("~p",[Message]).
위 프로그램의 출력은 다음과 같습니다.
산출
“Hello”
Pid! 메시지
식별자 Pid를 사용하여 프로세스에 메시지를 보냅니다. 메시지 전송은 비동기식입니다. 발신자는 기다리지 않고하던 일을 계속합니다.‘!’ 송신 연산자라고합니다.
예는 다음과 같습니다-
예
-module(helloworld).
-export([start/0]).
start() ->
Pid = spawn(fun() -> server("Hello") end),
Pid ! {hello}.
server(Message) ->
io:fwrite("~p",[Message]).
받기… 끝
프로세스로 전송 된 메시지를 수신합니다. 다음과 같은 구문이 있습니다.
통사론
receive
Pattern1 [when Guard1] ->
Expressions1;
Pattern2 [when Guard2] ->
Expressions2;
...
End
메시지가 프로세스에 도착하면 시스템은이를 Pattern1 (보호 Guard1 사용 가능)과 일치 시키려고합니다. 이것이 성공하면 Expressions1을 평가합니다. 첫 번째 패턴이 일치하지 않으면 Pattern2를 시도합니다. 일치하는 패턴이 없으면 나중에 처리 할 수 있도록 메시지가 저장되고 프로세스는 다음 메시지를 기다립니다.
다음 프로그램에는 3 개의 명령이 모두 포함 된 전체 프로세스의 예가 나와 있습니다.
예
-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}.
위 프로그램에 대해 다음 사항에 유의해야합니다.
루프 기능에는 수신 종료 루프가 있습니다. 따라서 메시지가 전송되면 수신 종료 루프에 의해 처리됩니다.
루프 기능으로 이동하는 새로운 프로세스가 생성됩니다.
메시지는 Pid를 통해 생성 된 프로세스로 전송됩니다. 메시지 명령.
위 프로그램의 출력은 다음과 같습니다.
산출
Area of the Rectangle is 60
최대 프로세스 수
동시성에서는 시스템에서 허용되는 최대 프로세스 수를 결정하는 것이 중요합니다. 그러면 시스템에서 동시에 실행할 수있는 프로세스 수를 이해할 수 있어야합니다.
시스템에서 실행할 수있는 최대 프로세스 수를 결정하는 방법의 예를 살펴 보겠습니다.
-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) microseconds~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).
처리 능력이 좋은 컴퓨터에서는 위의 최대 기능이 모두 통과됩니다. 다음은 위 프로그램의 샘플 출력입니다.
Maximum allowed processes:262144
Process spawn time=47.0 (16.0) microseconds
Maximum allowed processes:262144
Process spawn time=12.81 (10.15) microseconds
시간 초과로 받기
때때로 receive 문은 오지 않는 메시지를 영원히 기다릴 수 있습니다. 여러 가지 이유가있을 수 있습니다. 예를 들어, 프로그램에 논리적 오류가 있거나 메시지를 보내려는 프로세스가 메시지를 보내기 전에 충돌했을 수 있습니다. 이 문제를 방지하기 위해 receive 문에 제한 시간을 추가 할 수 있습니다. 프로세스가 메시지 수신을 대기하는 최대 시간을 설정합니다.
다음은 제한 시간이 지정된 수신 메시지의 구문입니다.
통사론
receive
Pattern1 [when Guard1] ->
Expressions1;
Pattern2 [when Guard2] ->
Expressions2;
...
after Time ->
Expressions
end
가장 간단한 예는 다음 프로그램과 같이 sleeper 함수를 만드는 것입니다.
예
-module(helloworld).
-export([sleep/1,start/0]).
sleep(T) ->
receive
after T ->
true
end.
start()->
sleep(1000).
위의 코드는 실제로 종료되기 전에 1000Ms 동안 휴면합니다.
선택적 수신
Erlang의 각 프로세스에는 연결된 사서함이 있습니다. 프로세스에 메시지를 보내면 메시지가 사서함에 저장됩니다. 이 메일 함이 검사되는 유일한 시간은 프로그램이 수신 명령문을 평가할 때입니다.
다음은 선택적 수신 문의 일반 구문입니다.
통사론
receive
Pattern1 [when Guard1] ->
Expressions1;
Pattern2 [when Guard1] ->
Expressions1;
...
after
Time ->
ExpressionTimeout
end
이것은 위의 수신 문이 작동하는 방법입니다-
receive 문을 입력하면 타이머가 시작됩니다 (그러나 표현식에 after 섹션이있는 경우에만 해당).
사서함의 첫 번째 메시지를 가져 와서 Pattern1, Pattern2 등과 일치 시키십시오. 일치가 성공하면 메일 함에서 메시지가 제거되고 패턴 다음의 표현식이 평가됩니다.
receive 문의 패턴이 메일 함의 첫 번째 메시지와 일치하지 않으면 첫 번째 메시지가 메일 함에서 제거되고 "저장 대기열"에 배치됩니다. 그런 다음 사서함의 두 번째 메시지가 시도됩니다. 이 절차는 일치하는 메시지를 찾거나 사서함의 모든 메시지를 검사 할 때까지 반복됩니다.
사서함의 메시지 중 일치하는 메시지가 없으면 프로세스가 일시 중단되고 다음에 새 메시지가 사서함에 들어갈 때 실행을 위해 다시 예약됩니다. 새 메시지가 도착하면 저장 대기열의 메시지가 다시 일치하지 않습니다. 새 메시지 만 일치합니다.
메시지가 일치하는 즉시 저장 큐에 넣은 모든 메시지는 프로세스에 도착한 순서대로 메일함에 다시 입력됩니다. 타이머가 설정되어 있으면 지워집니다.
메시지를 기다리는 동안 타이머가 경과하면 ExpressionsTimeout 표현식을 평가하고 저장된 메시지를 프로세스에 도착한 순서대로 사서함에 다시 넣습니다.