erlang “0后接收”(也称为选择性接收)的用途

flvlnr44  于 2022-12-08  发布在  Erlang
关注(0)|答案(4)|浏览(219)

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
.

我错过了什么?
附言:我在爱尔朗R16 B 03 -1上,这本书的作者,正如我记得的那样,是在爱尔朗R13上。

icnyk63a

icnyk63a1#

每个进程都有一个“邮箱”--消息队列。消息可以通过receive来获取。如果队列中没有消息,after部分指定了“receive”将等待它们多长时间。因此after 0--意味着进程检查(通过receive)队列中是否有消息,如果队列为空,则立即继续下一个指令。
例如,如果我们想定期检查这里是否有任何消息,如果没有消息,我们可以使用它来做一些事情(希望有帮助)。

8tntrjer

8tntrjer2#

假设after 0finally
考虑使用after 0来处理具有优先级的receive:http://learnyousomeerlang.com/more-on-multiprocessing#selective-receives
愿这种对事物的不同看法启发你。

sxissh06

sxissh063#

您可以使用以下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>
kmbjn2e3

kmbjn2e34#

如果您不打算使用嵌套接收,而不是使用“after”部分,我认为更好的方法是使用“Unexpected -〉”变量来处理所有不匹配的消息。

相关问题