English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Erlang의 병행 프로그래밍은 다음과 같은 기본 원칙이나 절차를 따라야 합니다.
리스트는 다음과 같은 원칙을 포함합니다:
piD = spawn(Fun)
Fun을 평가하는 새로운 병행 프로세스를 생성합니다. 새로운 프로세스는 호출자와 병행하여 실행됩니다. 한 실례가 다음과 같습니다-
-module(helloworld). -export([start/0]). start() -> spawn(fun()) -> server("Hello") end). server(Message) -> io:fwrite("~p", [Message]).
위 프로그램의 출력은-
"Hello"
지정자 Pid를 통해 프로세스에 메시지를 보냅니다. 메시지 전송은 비동기적입니다. 보내는 측은 기다리지 않고 계속 활동을 계속합니다. "!"이 보내기 연산자로 불립니다.
한 실례가 다음과 같습니다-
-module(helloworld). -export([start/0]). start() -> Pid = spawn(fun() -> server("Hello") end), Pid ! {hello}. server(Message) -> io:fwrite("~p", [Message]).
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 표현식을 평가하고 모든 저장된 메시지를 도착 순서대로 이메일함으로 돌려보내세요.