关于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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值