2014-03-02 68 views
2

Learn You Some Erlang for Great Good!目的`接收後0`

另一種特殊情況是,當超時爲0:

flush() -> 
    receive 
    _ -> flush() 
    after 0 -> 
    ok 
    end 
. 

當這種情況發生,Erlang的虛擬機將試圖找到一條消息這適合 可用模式之一。在上面的情況下,任何匹配。由於 只要有消息,flush/0函數將遞歸調用 本身,直到郵箱爲空。一旦完成,代碼的ok部分被執行,函數返回。

我不明白after 0的用途。閱讀上面的文字後,我還以爲是像after infinity(永遠等待),但我改變一點點沖洗功能:

flush2() -> 
    receive 
    _ -> timer:sleep(1000), io:format("aa~n"), flush() 
    after 0 -> 
    okss 
    end 
. 

flush3() -> 
    receive 
    _ -> io:format("aa~n"), flush() 
    after 0 -> 
    okss 
    end 
. 

在等待1秒第一功能和第二功能,它不會等待。
在這兩種情況下,它都不顯示文字(aa~n)。
因此它不起作用after infinity

如果receiveafter之間的塊不那麼上述2級執行的代碼可以簡化爲:

flush4() -> 
    okss 
. 

什麼我失蹤?

ps。我記得Erlang R16B03-1,我記得這本書的作者是在Erlang R13上。

回答

11

每個進程都有一個「郵箱」 - 消息隊列。消息可以通過'receive'獲取。如果隊列中沒有消息。 ''部分指定'接收多少時間後將等待它們'。所以。 '0之後' - 表示進程檢查(通過'receive')如果隊列中有消息並且隊列爲空立即繼續下一個指令。

例如,如果我們希望定期檢查這裏是否有消息,並且在沒有消息的情況下執行某些操作(希望有幫助),則可以使用它。

3

您可以用下面的shell命令玩理解命令後的效果:

4> L = fun(G) ->        
4> receive         
4> stop -> ok;        
4> M -> io:format("received ~p~n",[M]), G(G) 
4> after 0 ->        
4> io:format("no message~n")     
4> end 
4> end. 
#Fun<erl_eval.6.80484245> 
5> F = fun() -> timer:sleep(10000),   
5> io:format("end of wait for messages, go to receive block~n"), 
5> L(L)end. 
#Fun<erl_eval.20.80484245> 
6> spawn(F).         
<0.46.0> 
end of wait for messages, go to receive block 
no message 
7> P1 = spawn(F). 
<0.52.0> 
8> P1 ! hello. 
hello 
end of wait for messages, go to receive block 
received hello 
no message 
9> P2 ! hello, P2 ! stop. 
* 1: variable 'P2' is unbound 
8> P2 = spawn(F).   
<0.56.0> 
9> P2 ! hello, P2 ! stop. 
stop 
end of wait for messages, go to receive block 
received hello 
10>