咨询Erlang中退出、错误与链接、监视器、系统进程的交互逻辑
Erlang错误处理场景与结果梳理
一、进程退出的几种触发情况
- 主动退出:自己调用
exit(Reason)终止自身,或者调用exit(Pid, Reason)主动终止其他进程 - 运行时错误崩溃:比如除以0、调用不存在的函数、模式匹配失败这类情况,退出Reason是对应的错误元组(像
{badarith, ...}) - 正常结束:进程执行完所有代码,或者主动调用
exit(normal),此时Reason为normal
二、进程间的三种关联机制
- 链接(Link):通过
link(Pid)建立,属于双向绑定,默认情况下一方退出会向另一方发送退出信号 - 监视(Monitor):通过
erlang:monitor(process, Pid)建立,是单向关联,被监视进程退出时,监视方会收到{'DOWN', Ref, process, Pid, Reason}消息 - 系统进程:指OTP框架中的进程(如gen_server、gen_fsm),自带错误处理逻辑,通常由监督者(Supervisor)管理,遵循OTP重启规则
三、不同组合场景下的预期结果
1. 进程无关联时
不管是主动退出、崩溃还是正常结束,只有当前进程终止,其他进程不会收到任何信号或消息(除非存在监视关系)
2. 链接进程的交互场景
场景A:A与B链接,A主动退出(Reason非normal)
- A终止,向B发送退出信号
- 若B未设置
process_flag(trap_exit, true):B会被连带终止,并将A的退出Reason传递给自己的链接进程(如果有的话) - 若B设置了
trap_exit:B不会终止,会收到{'EXIT', PidA, Reason}消息,可自行处理
场景B:A与B链接,A正常结束(Reason=normal)
- A终止,但不会向B发送退出信号,B不受任何影响
场景C:调用exit(PidB, Reason)终止与A链接的B
- B终止,向A发送退出信号,后续结果同场景A,取决于A是否设置
trap_exit
3. 监视进程的交互场景
场景A:A监视B,B以任意Reason退出
- B终止,A一定会收到
{'DOWN', Ref, process, PidB, Reason}消息,哪怕B是正常结束 - A不会被终止,除非自己处理消息时触发错误
场景B:A监视B,但A先终止
- 监视关系自动解除,B不受任何影响
4. OTP系统进程的错误处理
- 系统进程默认设置
process_flag(trap_exit, true),可捕获退出信号 - 若系统进程因运行时错误崩溃,会先调用对应终止回调(如gen_server的
terminate/2),再根据监督者的重启策略执行:permanent:无论退出Reason是什么,监督者都会重启该进程transient:仅当Reason不是normal或shutdown时重启temporary:无论何种情况都不重启
- 系统进程间的链接通常由监督者管理,监督者会根据子进程的退出Reason决定是否终止其他子进程
四、关键注意点
- 链接是双向绑定,监视是单向关联,这是两者核心区别
trap_exit仅影响当前进程是否会被退出信号终止,捕获到的退出消息可自行处理exit(Pid, kill)是强制终止,目标进程无法捕获,会直接终止并向链接进程发送kill退出信号
内容的提问来源于stack exchange,提问作者Esteis
相关产品推荐
相关产品推荐

