亚洲区国产区激情区无码区,国产成人mv视频在线观看,国产A毛片AAAAAA,亚洲精品国产首次亮相在线

Erlang 并發(fā)

Erlang 的并發(fā)編程需要遵循以下基本原則或過程。

列表包括以下原則:

piD = spawn(Fun)

創(chuàng)建一個(gè)評(píng)估 Fun 的新并發(fā)進(jìn)程。新進(jìn)程與調(diào)用方并行運(yùn)行。一個(gè)實(shí)例如下-

實(shí)例

-module(helloworld). 
-export([start/0]). 

start() ->
   spawn(fun() -> server("Hello") end). 

server(Message) ->
   io:fwrite("~p",[Message]).

上面程序的輸出是-

輸出

“Hello”

Pid ! Message

用標(biāo)識(shí)符 Pid 向進(jìn)程發(fā)送消息。消息發(fā)送是異步的。發(fā)送者不會(huì)等待,而是繼續(xù)它正在做的事情?!埃 环Q為發(fā)送運(yùn)算符。

一個(gè)實(shí)例如下-

實(shí)例

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

server(Message) ->
   io:fwrite("~p",[Message]).

Receive…end

接收已發(fā)送到進(jìn)程的消息。它具有以下語法-

語法

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

當(dāng)消息到達(dá)該進(jìn)程時(shí),系統(tǒng)會(huì)嘗試將其與Pattern1匹配(可能有Guard 1)。如果成功,則對(duì)Expressions1求值。如果第一個(gè)模式不匹配,則嘗試使用Pattern2,依此類推。如果沒有任何一個(gè)模式匹配,則保存該消息以供以后處理,然后該過程等待下一條消息。

以下程序顯示了使用全部3個(gè)命令的整個(gè)過程的示例。

實(shí)例

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

關(guān)于上述程序,需要注意以下幾點(diǎn):

  • loop函數(shù)具有接收端循環(huán)。因此,當(dāng)消息被發(fā)送時(shí),它將被接收端循環(huán)處理。

  • 生成一個(gè)新進(jìn)程,該進(jìn)程將轉(zhuǎn)到循環(huán)函數(shù)。

  • 通過 Pid! message 命令將消息發(fā)送到產(chǎn)生的進(jìn)程。

上面程序的輸出是-

輸出

Area of the Rectangle is 60

最大進(jìn)程數(shù)

并發(fā)地,重要的是確定系統(tǒng)上允許的最大進(jìn)程數(shù)。然后,您應(yīng)該能夠了解系統(tǒng)上可以同時(shí)執(zhí)行多少個(gè)進(jìn)程。

讓我們看一個(gè)示例,該示例如何確定系統(tǒng)上可以執(zhí)行的最大進(jìn)程數(shù)。

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

在任何具有良好處理能力的機(jī)器上,上述兩個(gè)最大函數(shù)都會(huì)通過。下面是上述程序的一個(gè)示例輸出。

Maximum allowed processes:262144
Process spawn time=47.0 (16.0) microseconds
Maximum allowed processes:262144
Process spawn time=12.81 (10.15) microseconds

超時(shí)接收

有時(shí),receive語句可能會(huì)永遠(yuǎn)等待一條永遠(yuǎn)不會(huì)出現(xiàn)的消息。這可能有很多原因。例如,我們的程序中可能存在邏輯錯(cuò)誤,或者要向我們發(fā)送消息的進(jìn)程在發(fā)送消息之前可能已經(jīng)崩潰。為了避免這個(gè)問題,我們可以在receive語句中添加一個(gè)超時(shí)。這將設(shè)置進(jìn)程等待接收消息的最長時(shí)間。

以下是指定了超時(shí)的接收消息的語法

語法

receive 
Pattern1 [when Guard1] -> 
Expressions1; 

Pattern2 [when Guard2] ->
Expressions2; 
... 
after Time -> 
Expressions 
end

最簡單的實(shí)例是創(chuàng)建一個(gè)sleeper函數(shù),如下面的程序所示。

實(shí)例

-module(helloworld). 
-export([sleep/1,start/0]). 

sleep(T) ->
   receive 
   after T -> 
      true 
   end. 
   
start()->
   sleep(1000).

上述代碼在實(shí)際退出之前將休眠1000毫秒。

選擇性接收

Erlang中的每個(gè)進(jìn)程都有一個(gè)關(guān)聯(lián)的郵箱。當(dāng)您向該進(jìn)程發(fā)送消息時(shí),該消息將放入郵箱中。僅當(dāng)程序評(píng)估接收語句時(shí),才檢查此郵箱。

以下是“選擇性接收”語句的一般語法。

語法

receive 
Pattern1 [when Guard1] ->
Expressions1; 

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

這就是上面的接收語句的工作方式-

  • 當(dāng)我們輸入一個(gè)receive語句時(shí),我們將啟動(dòng)一個(gè)計(jì)時(shí)器(但前提是表達(dá)式中存在一個(gè)after節(jié))。

  • 以郵箱中的第一封郵件,并嘗試使其與Pattern1,Pattern2等匹配。如果匹配成功,將從郵箱中刪除該郵件,并評(píng)估模式后面的表達(dá)式。

  • 如果receive語句中的任何模式都不匹配郵箱中的第一條消息,則將從郵箱中刪除第一條消息并將其放入“保存隊(duì)列”。然后嘗試郵箱中的第二條消息。重復(fù)此過程,直到找到匹配的消息或檢查了郵箱中的所有消息為止。

  • 如果郵箱中的所有郵件都不匹配,則該過程將被掛起,并將在下次將新郵件放入郵箱中時(shí)重新安排執(zhí)行時(shí)間。請(qǐng)注意,當(dāng)收到新消息時(shí),保存隊(duì)列中的消息將不重新匹配;僅匹配新消息。

  • 一旦匹配了一條消息,所有放入保存隊(duì)列的消息就會(huì)按照到達(dá)過程的順序重新輸入到郵箱中。如果設(shè)置了計(jì)時(shí)器,則將其清除。

  • 如果在等待消息時(shí)計(jì)時(shí)器已過去,請(qǐng)?jiān)u估表達(dá)式ExpressionsTimeout并將所有保存的消息按到達(dá)過程的順序放回郵箱。