2015-10-16 58 views
2

最近我一直在試圖理解Erlang中的併發服務器。考慮下面的代碼向服務器發出請求。取決於特定的執行順序,可以通過3個進程打印不同的值。什麼是訂單?每個流程的最高價值和最低價值是多少?Erlang併發理解

test() -> 
    Server = start(), 
    spawn(fun() -> 
        incr(Server), 
        io:format("Child 1 read ~p~n", [read(Server)]) end), 
    incr(Server), 
    spawn(fun() -> 
        incr(Server), 
        io:format("Child 2 read ~p~n", [read(Server)]) end), 
    io:format("Parent read ~p~n", [read(Server)]). 

的代碼執行鍼對下面的服務器:

-module(p4). 
-export([start/0, init/0, read/1, incr/1, reset/1]). 

start() -> 
    spawn(fun() -> init() end). 
init() -> loop(0). 

loop(N) -> 
    receive 
     {read, Pid} -> 
      Pid ! {value, self(), N}, 
      loop(N); 
     {incr, Pid} -> 
      Pid ! {incr_reply, self()}, 
      loop(N+1); 
     {reset, Pid} -> 
      Pid ! {reset_reply, self()}, 
      loop(0) 
    end. 

read(Serv) -> 
    Serv ! {read, self()}, 
    receive {value, Serv, N} -> N end. 
incr(Serv) -> 
    Serv ! {incr, self()}, 
    receive {incr_reply, Serv} -> ok end. 
reset(Serv) -> 
    Serv ! {reset, self()}, 
    receive {reset_reply, Serv} -> ok end. 
  • 父:最低= 1最高= 3
  • Child1:最低= 1最高= 3
  • CHILD2:最低= 1最高= 2

我不完全確定o rders,但我想這可能是因爲:

  • Child1可以讀1,2和3
  • 家長可以讀1,2和3
  • CHILD2可以讀取1和2

這對於最低價值,最高價值和訂單都是正確的嗎?

+0

[Erlang服務器請求次序]的可能重複(http://stackoverflow.com/questions/32992743/erlang-server-request-order) –

+0

這是類似的概念,但我只想知道如果我做了正確的時間。試圖瞭解輸出的順序。 –

回答

1

循環中的初始值爲0.服務器的增量操作在執行增量前回復調用者,但這並不重要,因爲在發送該回復和實際增量之間沒有處理消息。每個讀取的消息都會得到一個包含所有之前到達的增量消息的效果的回覆。由於保證了消息從一個進程到另一個進程的順序,任何增加讀取的進程都能保證讀取至少自己的增量。服務器的讀操作只是以當前循環值回覆。重置操作未使用。

Child1遞增,然後讀取。它最初與Parent同時運行,然後與Child2同時運行,兩者都會增加。因此,它可以從它自己的增量中讀取1,從它自己的增量中讀取2,也可以從它的父項中讀取1,如果它的讀取也從Child2中讀取增量,則讀取3。

Child2也增加,然後讀取,但直到Parent已增加後纔開始。因此它可以讀取的最小值是2,因爲它可以與Child1同時運行,所以它可以選擇讀取一個3.

父增量然後讀取,所以它可以讀取的最小值是1.它的讀取與Child1同時運行, Child2,所以如果它的讀取發生在它們的任何一個增量之前,它就會看到一個1.如果它的讀取選擇了任一個子增量,或者如果它讀取了兩個子增量,則它可以讀取一個2。

+0

只需很少的附錄,所有三個輸出都可以以任何順序出現在控制檯中,因爲它們是從三個獨立進程發送的消息。 –