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]).
The output of the above program is-
"Hello"
用标识符 Pid 向进程发送消息。消息发送是异步的。发送者不会等待,而是继续它正在做的事情。“!’被称为发送运算符。
一个实例如下-
-module(helloworld). -export([start/0]). start(). -> Pid = spawn(fun() -> server("Hello") end), Pid ! {hello}. server(Message) -> io:fwrite("~p", [Message]).
Receive messages that have been sent to the process. It has the following syntax-
empfangen Muster1 [wenn Guard1] -> Ausdrücke1; Muster2 [wenn Guard2] -> Ausdrücke2; ... End
When a message arrives at the process, the system tries to match it with Pattern1Matching (may have Guard 1). If successful, evaluate the Expressions1Evaluation. 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 a command.
-module(helloworld). -export([loop/0, start/0]). loop() -> empfangen {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 loop. Therefore, when a message is sent, it will be processed by the receiving 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 look at 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), {_, Zeit1} = statistics(runtime), {_, Zeit2} = statistics(wall_clock), lists:foreach(fun(Pid) -> Pid ! sterben end, L), U1 = Zeit1 * 1000 / N, U2 = Zeit2 * 1000 / N, io:format("Prozess spawn Zeit=~p (~p) Mikrosekunden~n", [U1, U2]). warten() -> empfangen sterben -> void end. für(N, N, F) -> [F()]; für(I, N, F) -> [F()|für(I+1, N, F)]. start().-> max(1000), max(100000).
Auf jedem gut funktionierenden Computer passieren die beiden obigen maximalen Funktionen. Hier ist ein Beispiel für die Ausgabe des obigen Programms.
Maximal erlaubte Prozesse:262144 Prozess spawn Zeit=47.0 (16.0) Mikrosekunden Maximal erlaubte Prozesse:262144 Prozess spawn Zeit=12.81 (10.15) Mikrosekunden
Manchmal kann ein receive-Statement für immer auf eine nie eintreffende Nachricht warten. Dies kann viele Gründe haben. Zum Beispiel könnte es in unserem Programm logische Fehler geben oder der Prozess, der uns Nachrichten senden soll, könnte bereits vor dem Senden des Nachrichten abgestürzt sein. Um dieses Problem zu vermeiden, können wir eine Zeitüberschreitung im receive-Statement hinzufügen. Dies stellt die maximale Zeit ein, die der Prozess für die Wartezeit auf eine empfangene Nachricht einstellen kann.
Hier ist die Grammatik des Empfangs von Nachrichten mit Zeitüberschreitung.
empfangen Muster1 [wenn Guard1] -> Ausdrücke1; Muster2 [wenn Guard2] -> Ausdrücke2; ... nach Zeit -> Ausdrücke end
Der einfachste Beispiel ist die Erstellung einer sleeper-Funktion, wie im folgenden Programm gezeigt.
-module(helloworld). -export([sleep/1,start/0]). sleep(T) -> empfangen nach T -> wahr end. start().-> sleep(1000).
Der obige Code wird vor dem tatsächlichen Beenden schlafen1000 Millisekunden.
Jeder Prozess in Erlang hat eine zugeordnete E-Mailbox. Wenn Sie eine Nachricht an diesen Prozess senden, wird die Nachricht in die E-Mailbox eingefügt. Diese E-Mailbox wird nur überprüft, wenn das Programm das Empfangsstatement bewertet.
Hier ist die allgemeine Grammatik des "auswählenden Empfangs"-Statements.
empfangen Muster1 [wenn Guard1] -> Ausdrücke1; Muster2 [wenn Guard1] -> Ausdrücke1; ... nach Zeit -> ExpressionTimeout end
Dies ist die Arbeitsweise des obigen Empfangsstatements-
Wenn wir einen receive-Ausdruck eingeben, starten wir einen Timer (vorausgesetzt, es gibt einen after-Abschnitt im Ausdruck).
mit der ersten E-Mail im Briefkasten und versuchen, sie mit Muster zu übereinstimmen1,Muster2Warten. Wenn eine Übereinstimmung erfolgreich ist, wird das E-Mail aus dem Briefkasten gelöscht und der Ausdruck nach dem Muster bewertet.
Wenn kein Muster im receive-Ausdruck mit der ersten Nachricht im Briefkasten übereinstimmt, wird die erste Nachricht aus dem Briefkasten gelöscht und in die 'Speicherwarteschlange' eingefügt. Versuchen Sie dann die zweite Nachricht im Briefkasten. Wiederholen Sie diesen Vorgang, bis eine Übereinstimmung gefunden oder alle Nachrichten im Briefkasten überprüft wurden.
Wenn alle Briefe im Briefkasten nicht gematcht werden, wird der Prozess angehalten und wird bei der nächsten Einfügung eines neuen Briefes in den Briefkasten neu geplant. Beachten Sie, dass bei Empfang neuer Nachrichten Nachrichten in der Speicherwarteschlange nicht neu gematcht werden; nur die neue Nachricht wird gematcht.
Sobald eine Nachricht gematcht wurde, werden alle Nachrichten, die in die Speicherwarteschlange eingefügt wurden, in der Reihenfolge ihres Eintreffens neu in den Briefkasten eingefügt. Wenn ein Timer gesetzt wurde, wird er gelöscht.
Wenn der Timer abgelaufen ist, während Sie auf eine Nachricht warten, bewerten Sie den Ausdruck ExpressionsTimeout und geben Sie alle gespeicherten Nachrichten in der Reihenfolge ihres Eintreffens zurück in den Briefkasten.