关于erlang link进程间需要注意的一个问题(normal退出信号)

下面是测试代码,
我们启动两个进程,两个进程间进行链接,但是发现在 一个进程结束的时候另一个进程竟然没有跟着一起结束,
从打印看也没有接到任何消息
 
 
t() ->
    spawn_link(fun() -> a() end).
 
 
a() ->
    receive
        c ->
            X = spawn_link(fun() -> b() end),
            io:format("pid:~p",[X]),
            a();
        E ->
            io:format("a msg:~p",[E])
    end.
 
 
b() ->
    receive
        Msg ->
            io:format("msg:~p", [Msg]),
            b()
    end.
 
 
下面是测试过程:
一.
1> lib_performance_tests:t().
<0.32.0>
2> pid(0,32,0) ! c.
pid:<0.34.0>c
3> process_info(pid(0,34,0)).
[{current_function,{lib_performance_tests,b,0}},
 {initial_call,{erlang,apply,2}},
 {status,waiting},
 {message_queue_len,0},
 {messages,[]},
 {links,[<0.32.0>]},
 {dictionary,[]},
 {trap_exit,false},
 {error_handler,error_handler},
 {priority,normal},
 {group_leader,<0.23.0>},
 {total_heap_size,233},
 {heap_size,233},
 {stack_size,1},
 {reductions,3},
 {garbage_collection,[{min_bin_vheap_size,46368},
                      {min_heap_size,233},
                      {fullsweep_after,65535},
                      {minor_gcs,0}]},
 {suspending,[]}]
4> pid(0,32,0) ! stop.
a msg:stopstop
5> process_info(pid(0,34,0)).
 
[{current_function,{lib_performance_tests,b,0}},
 {initial_call,{erlang,apply,2}},
 {status,waiting},
 {message_queue_len,0},
 {messages,[]},
 {links,[]},
 {dictionary,[]},
 {trap_exit,false},
 {error_handler,error_handler},
 {priority,normal},
 {group_leader,<0.23.0>},
 {total_heap_size,233},
 {heap_size,233},
 {stack_size,1},
 {reductions,3},
 {garbage_collection,[{min_bin_vheap_size,46368},
                      {min_heap_size,233},
                      {fullsweep_after,65535},
                      {minor_gcs,0}]},
 {suspending,[]}]
6> process_info(pid(0,32,0)).
 
undefined
启动 a, b两个进程,互相连接 a正常结束,b没有收到退出信号
 
 
 
二.
 
1> lib_performance_tests:t().
<0.32.0>
2> pid(0,32,0) ! c.
pid:<0.34.0>c
3> process_info(pid(0,34,0)).
[{current_function,{lib_performance_tests,b,0}},
 {initial_call,{erlang,apply,2}},
 {status,waiting},
 {message_queue_len,0},
 {messages,[]},
 {links,[<0.32.0>]},
 {dictionary,[]},
 {trap_exit,false},
 {error_handler,error_handler},
 {priority,normal},
 {group_leader,<0.23.0>},
 {total_heap_size,233},
 {heap_size,233},
 {stack_size,1},
 {reductions,3},
 {garbage_collection,[{min_bin_vheap_size,46368},
                      {min_heap_size,233},
                      {fullsweep_after,65535},
                      {minor_gcs,0}]},
 {suspending,[]}]
4> exit(pid(0,32,0),shutdown).
 
** exception exit: shutdown
5> process_info(pid(0,34,0)).
 
undefined
启动a,b两个进程,互相连接, 通过退出信号结束a进程,b进程结束
由此我们可以看到,并不是互相连接就会接受到退出信号使进程退出的源头是退出信号的方式结束才会导致进程结束
 
三.
 
我们把a方法的代码修改为:
a() ->
    receive
        c ->
            X = spawn_link(fun() -> b() end),
            io:format("pid:~p",[X]),
            a();
        E ->
            io:format("a msg:~p",[E]),
            list_to_atom(E)
    end.
 
 
 
这样我们向a进程发送hello,会出现异常,这样再去看的时候b进程就退出了.
 
 
 
 
 
 
 
原因总结:
      erlang关于退出信号这块有一张表
      根据捕获状态和退出信号,进程做不同的操作, 我们第一步的实验就是说产生了 normal退出信号,链接进程又不捕获,所以没有产生任何动作
      而其他情况的实验产生的退出信号均不是normal,所以链接进程退出,这个是需要开发者注意的一个东西.
     
   捕获状态              退出信号(原因)         动作
   
       true                     kill                      消亡,向链接的进程广播退出信号(killed)
       true                     X                        将{'EXIT', Pid, X} 加入到邮箱
       false                    normal               不做任何事
       false                    kill                       消亡,向链接的进程广播退出信号(killed)
       false                    X                         消亡,向链接的进程广播退出信号X
 
 
 
 

转载于:https://www.cnblogs.com/fangjie008/archive/2012/08/28/2660361.html

你可能感兴趣的:(关于erlang link进程间需要注意的一个问题(normal退出信号))