天天看点

OTP的supervisor tree如何保证子进程一定随父进程的退出而退出

利用otp行为包构建的应用之所以可靠,是因为我们按照otp的设计模式,将所有进程组织成了一棵可靠的supervisor tree。每一个supervisor监控其子进程,并在其子进程出错时按照重启策略进行相应的处理。

但是,你是否考虑过,如果supervisor意外终止,其子进程会怎样?当然,直觉告诉我们连监控进程的没有了,所有的子进程应全部终止。但是,你在代码中是否真正考虑过这种情况?你的gen_server可否写过如下代码?

事实上,无论你写不写上述代码,你的gen_server、gen_event和gen_fsm都会随其supervisor的结束而结束,但是这是为什么呢?

让我们来看看gen_server的源代码gen_server.erl:

loop是gen_server的主循环,gen_server在初始化结束后即会陷入loop循环,接收消息并交由decode_msg/8处理。

下面让我们来看看decode_msg/8的源代码:

在第351行我们可以看到,gen_server收到的所有消息在交由我们写的回调函数处理之前,已经在decode_msg/8中做过预处理,而其对{‘exit‘, parent, reason}的反应便是以相同reason退出。

在gen_fsm和gen_event中我们也能找到相同的处理,而supervisor本身是gen_server实现的,所以使用otp定义的四大行为构建的supervisor tree能够保证子进程总随父进程的退出而退出。