如果在接收块结束时不再调用该函数会发生什么? - 二郎

时间:2014-03-17 09:38:18

标签: erlang

这方面的一个例子是:

myFunction()
   receive 
      msg1 -> io:format("Message 1!~n"),
              self() ! msg1,
              myFunction();
      msg2 -> io:format("Message 2!~n")
end.

我学会了像msg1那样做我的消息;但最近我犯了一个错误并编译了类似于msg2的代码。当msg2发生时,之后会发生什么?该过程是否只是在msg2之后处于同一个接收状态并等待其他消息?

3 个答案:

答案 0 :(得分:4)

为什么不亲自尝试?

如果您在收到msg2后没有调用该函数,则无需再执行任何操作,您的进程将退出。

  

进程是否只是在msg2之后处于同一个接收状态并等待其他消息?

没有。您需要再次调用该函数。递归会创建一个循环。

  

当msg2发生时,之后会发生什么?

打印

Message 2!\n并且不再执行myFunction/0代码,如果当前进程没有其他任何操作,则退出。

答案 1 :(得分:2)

如果你不在接收块的末尾再次调用该函数,那么该过程将会死亡。(如果你是的话,如果你向进程发送msg2),但是如果你发送其他消息(msg1msg2除外),进程将等待,消息存储在进程的消息队列中。

-module(wy).
-compile(export_all).

myFunction() ->
receive 
    msg1 -> 
        io:format("Message 1!~n"),
        self() ! msg1,
        myFunction();
    msg2 -> 
        io:format("Message 2!~n")
end.
parent() ->
    Pid = spawn(fun myFunction/0),
    register(myFunction, Pid),
    erlang:monitor(process, Pid),
    receive
        Res -> io:format("Receive ~p~n", [Res])
    end.

main() ->
    spawn(fun() -> parent() end).

首先需要执行wy:main().

(1)如果执行myFunction ! msg22.,您可以发现进程myFunction仍然存在,并使用此命令erlang:process_info(whereis(myFunction), messages).,您可以找到消息msg22是存储在消息队列中。

(2)如果你执行myFunction ! msg2.,你可以得到这个输出

Message 2!
Receive {'DOWN',#Ref<0.0.0.108>,process,<0.48.0>,normal}
msg2

从这个输出中你可以知道进程myFunction已经死亡。

(3)如果执行myFunction ! msg1,过程将进入无限循环。

答案 2 :(得分:0)

其他答案几乎是正确的。如果您在收到msg2后没有进行递归调用,则该函数将结束,您将返回myFunction/0的调用者。然后它将取决于调用者发生了什么。如果这是该过程中的最后一件事,那么该过程将以原因normal终止,否则它将继续处理。

要记住的是,对receive的每次调用都只会处理一条消息,因此如果您要继续处理消息,则必须重复调用receive。因此myFunction中的递归。