English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Erlang 병목

Erlang의 병행 프로그래밍은 다음과 같은 기본 원칙이나 절차를 따라야 합니다.

리스트는 다음과 같은 원칙을 포함합니다:

piD = spawn(Fun)

Fun을 평가하는 새로운 병행 프로세스를 생성합니다. 새로운 프로세스는 호출자와 병행하여 실행됩니다. 한 실례가 다음과 같습니다-

예제

-module(helloworld). 
-export([start/0]). 
start() ->
   spawn(fun()) -> server("Hello") end). 
server(Message) ->
   io:fwrite("~p", [Message]).

위 프로그램의 출력은-

출력

"Hello"

Pid ! Message

지정자 Pid를 통해 프로세스에 메시지를 보냅니다. 메시지 전송은 비동기적입니다. 보내는 측은 기다리지 않고 계속 활동을 계속합니다. "!"이 보내기 연산자로 불립니다.

한 실례가 다음과 같습니다-

예제

-module(helloworld). 
-export([start/0]). 
start() -> 
   Pid = spawn(fun() -> server("Hello") end), 
   Pid ! {hello}. 
server(Message) ->
   io:fwrite("~p", [Message]).

Receive…end

sent to the process. It has the following syntax-

문법

receive
Pattern1 [when Guard1] ->
Expressions1;
Pattern2 [when Guard2] ->
Expressions2;
...
End

메시지가 해당 프로세스에 도착하면, 시스템은 그를 Pattern1matching(가드가 있을 수 있습니다) 1에valuating. 성공하면 Expressions1에valuating. 만약 첫 번째 패턴과 일치하지 않으면, Pattern2중 하나의 패턴과 일치하지 않으면 메시지를 보관하여 나중에 처리하고, 그 과정에서 다음 메시지를 기다립니다.

다음 프로그램은 전체3명령의 전체 과정의 예제.

예제

-module(helloworld). 
-export([loop/0, start/0]). 
loop() ->
   receive 
      {rectangle, Width, Ht} -> 
         io:fwrite("직사각형의 면적은 ~p~n", [Width * Ht]), 
         loop(); 
      {circle, R} ->
      io:fwrite("원의 면적은 ~p~n", [3.14159 * R * R]), 
      loop(); 
   기타 ->
      io:fwrite("Unknown"), 
      loop() 
   end. 
start() ->
   Pid = spawn(fun() -> loop() end), 
   Pid ! {rectangle, 6, 10}.

위 프로그램에 대해 주의해야 할 몇 가지 사항이 있습니다:

  • loop 함수는 수신 루프를 가지고 있습니다. 따라서 메시지가 전송되면 수신 루프가 처리합니다.

  • 새로운 프로세스를 생성하여 이 프로세스가 루프 함수로 이동합니다.

  • Pid! message 명령을 통해 생성된 프로세스에 메시지를 전송합니다.

위 프로그램의 출력은-

출력

직사각형의 면적은 60

최대 프로세스 수

병렬적으로, 시스템에서 허용할 수 있는 최대 프로세스 수를 결정하는 것이 중요합니다. 그런 다음, 시스템에서 동시에 실행할 수 있는 프로세스 수를 이해할 수 있어야 합니다.

이 예제를 통해 시스템에서 실행할 수 있는 최대 프로세스 수를 결정하는 방법을 보여드리겠습니다.

-module(helloworld). 
-export([max/1,start/0]). 
max(N) -> 
   Max = erlang:system_info(process_limit), 
   io:format("최대 허용 프로세스:~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) 마이크로초~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).

좋은 처리 능력을 가진 모든 기계에서 위의 두 가장 큰 함수는 통과합니다. 아래는 위 프로그램의 예제 출력입니다。

허용 가능한 최대 프로세스 수:262144
Process spawn time=47.0 (16.0) 마이크로초
허용 가능한 최대 프로세스 수:262144
Process spawn time=12.81 (10.15) 마이크로초

시간 초과 수신

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

위의 코드는 실제로 탈출하기 전까지 잠시 멈춥니다1000밀리초.

선택적 수신

Erlang의 각 프로세스는 관련된 이메일을 가지고 있습니다. 해당 프로세스에 메시지를 보내면, 메시지가 이메일에 저장됩니다. 수신 문장이 프로그램에서 평가될 때만 이 이메일을 확인합니다.

이하는 '선택적 수신' 문장의 일반 문법입니다。

문법

receive 
Pattern1 [when Guard1] ->
Expressions1; 
Pattern2 [when Guard1] ->
Expressions1; 
... 
after 
Time ->
ExpressionTimeout 
end

이것이 위의 수신 문장의 작동 방식입니다-

  • 当我们输入一个receive语句时,我们将启动一个计时器(但前提是表达式中存在一个after节)。

  • 입력하면, 표현식에 after 절이 존재하는 경우 시간 조정기를 시작합니다.1이메일함의 첫 번째 메시지와, Pattern2Pattern

  • 매칭을 기다립니다. 매칭이 성공하면 이메일함에서 이 메시지를 제거하고 패턴 뒤의 표현식을 평가합니다.

  • receive 문에서의 모든 패턴이 이메일함의 첫 번째 메시지와 매칭되지 않으면, 첫 번째 메시지를 이메일함에서 제거하고 '저장 큐'에 추가합니다. 그런 다음 이메일함의 두 번째 메시지를 시도합니다. 이 과정을 반복하여 매칭된 메시지를 찾거나 이메일함의 모든 메시지를 확인할 때까지 반복합니다.

  • 메시지가 하나도 매칭되지 않으면, 이 과정이 중지되고 다음에 새 메시지가 이메일함에 추가될 때 다시 실행 시간을 재설정됩니다. 주의하세요, 새 메시지를 받을 때 저장된 큐에 있는 메시지는 다시 매칭되지 않습니다; 새 메시지만 매칭됩니다.

  • 메시지를 기다리는 동안 타이머가 지났다면, ExpressionsTimeout 표현식을 평가하고 모든 저장된 메시지를 도착 순서대로 이메일함으로 돌려보내세요.