在《Erlang 并发编程基础一》中介绍了:如何新建一个进程和向一个进程发送消息,以及注册进程。而各进程之间没有任何关系。
本节主要介绍进程关系及其处理。
如果使用上节中的方式新建的进程,则进程是各自独立、互不依赖的,任何一个进程消亡都是无声的,它不会通过其它进程,其它进程也关心不到它。
但在程序中也会需要有进程之间依赖的关系,比如一个进程消亡会影响另一个进程或一个进程需要另一个进程服务,这时就需要建立进程间的关系,即建立“链接关系”。
建立进程链接关系的语法:
1.link(Pid) 即调用者通过调用这个函数将自身进程与进程号为Pid的进程建立链接关系,当其中一个退出时,会自动向另一个进程发送退出的消息。消息的形式为{'EXIT', Pid, Why},Why为进程退出的原因。
2.spawn_link(fun) 建立新进程的同时将新进程与自身进程链接。
当进程间建立链接时,如果一个进程退出时另一个进程也会退出,但这往往不是所想要的,一般会要求对退出信号进行处理,这样就要调用下面这个函数:
process_flag(trap_exit,true)
然后使用receive来接收其它进程退出信号并作适当的处理。
与链接进程有关的函数还有一些,你可以参考其它相关资料。
以下为一个基础程序实例:
-module(concur).
-compile(export_all).
exit_fun() ->
receive
X -> io:format("Exit fun Recv:~s~n",[X])
end.
main_fun() ->
process_flag(trap_exit,true),
Pid = spawn_link(fun exit_fun/0),
register(client,Pid),
receive
{'EXIT', Pid, Why} ->io:format("Recv EXIT:~s~n",[Why])
end.
程序中首先定义了一个函数exit_fun/0,当函数运行后会等待一个消息,收到消息后只是简单的输出到控制台,函数就会运行结束。如果把它作为一个单独的进程启动的话,就会因运行结束而正常退出进程。
main_fun/0函数中,首先调用了process_flag/2指示了该进程要处理与其链接进程的退出消息,然后通过spawn_link/1启动了新进程并与其链接,之后将启动的进程注册名称为client,最后等待接收与其链接进程的退出消息,并将其直接输出到控制台。
下图是在交互式环境下调用和运行的结果:
语句3通过调用spawn/3,将concur模块的main_fun/0生成一个新的进程;
语句4使用发送消息的语法,向注册名为client的进程(main_fun/0函数中注册的)发送一个字符串;
其后显示的信息依次是:启动exit_fun进程收到的消息、启动main_fun的进程收到的退出消息和语句4返回的值。其中normal表示进程exit_fun正常退出。
文章摄像头公众号: