“收到0后”的目的

时间:2014-03-02 19:44:43

标签: erlang

来自 Learn You Some Erlang for Great Good!

  

另一种特殊情况是超时为0:

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

当发生这种情况时,Erlang VM将尝试找到适合的消息   其中一种可用的模式。在上面的例子中,任何匹配。如   只要有消息,flush/0函数将递归调用   本身直到邮箱为空。完成后,after 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上。

3 个答案:

答案 0 :(得分:11)

每个进程都有一个“邮箱” - 邮件队列。消息可以通过'receive'获取。如果队列中没有消息。 'after'部分指定'接收时间等待它们的时间。所以。 'after 0' - 表示进程检查(通过'receive')如果队列中的任何消息和队列是空的,则立即继续执行下一条指令。

如果我们想在这里定期检查是否有任何消息并且在没有消息的情况下做某事(希望有帮助),可以使用它。

答案 1 :(得分:3)

您可以使用以下shell命令来了解after命令的效果:

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> 

答案 2 :(得分:2)

after 0视为finally

考虑使用after 0来优先处理receivehttp://learnyousomeerlang.com/more-on-multiprocessing#selective-receives

愿这些不同的东西启发你。