这方面的一个例子是:
myFunction()
receive
msg1 -> io:format("Message 1!~n"),
self() ! msg1,
myFunction();
msg2 -> io:format("Message 2!~n")
end.
我学会了像msg1那样做我的消息;但最近我犯了一个错误并编译了类似于msg2的代码。当msg2发生时,之后会发生什么?该过程是否只是在msg2之后处于同一个接收状态并等待其他消息?
答案 0 :(得分:4)
为什么不亲自尝试?
如果您在收到msg2
后没有调用该函数,则无需再执行任何操作,您的进程将退出。
进程是否只是在msg2之后处于同一个接收状态并等待其他消息?
没有。您需要再次调用该函数。递归会创建一个循环。
打印当msg2发生时,之后会发生什么?
Message 2!\n
并且不再执行myFunction/0
代码,如果当前进程没有其他任何操作,则退出。
答案 1 :(得分:2)
如果你不在接收块的末尾再次调用该函数,那么该过程将会死亡。(如果你是的话,如果你向进程发送msg2
),但是如果你发送其他消息(msg1
和msg2
除外),进程将等待,消息存储在进程的消息队列中。
-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
中的递归。