erlang supervisor

Supervisor 简析

-module(sup).
-behaviour(supervisor).

-export([start_link/0]).
-export([init/1]).

start_link() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).

init([]) ->
    {ok, {{one_for_one, 1, 60},
          [{ch3, {ch3, start_link, []},
            permanent, 5000, worker, [ch3]}]}}.

这里写图片描述

  • 方形表示督程(监督者supervisor process)它负责看管它下面的进程(子进程),并且可在必要的时候重启或终止它的子进程;圆形表示佣程(工作者worker process)真正工作的进程。督程下面监督的不一定是佣程,也可以监督督程。
  • 监督规则:上面提到了督程可以重启或终止它的子进程,如何重启终止是由一个子规程列表决定的,子进程按照列表中指定的顺序启动,并按相反的顺序终止。
  • 子规则列表:
child_spec() = #{id => child_id(),       
                 startFun => mfargs(),      
                 restart => restart(),   
                 shutdown => shutdown(), 
                 type => worker(),       
                 modules => modules()}  
id = term()
StartFunc = {M, F, A}  
M = F = atom()   
A = [term()] 
Restart = permanent | transient | temporary  
Shutdown = brutal_kill | integer() >= 0 | infinity   
Type = worker | supervisor    
Modules = [Module] | dynamic      
Module = atom()

其中,

参数解析
id督程的内部标识子规范
StartFunc用于创建和link一个子进程,必须是{M,F,A}的term格式,内部会用 apply(M, F, A)来创建,并且返回值必须是{ok,Child} or {ok, Child, Info},其中Child是子进程的PID, Info会被supervisor所忽略。
Restart这个参数用来告知子进程死掉时能否重启它,怎么重启;1、permanent表示总是能被重启(默认用permanent);2、temporary永远不能被重启;3、transient表示如果子进程是因为异常退出时才会被重启,即不是因normal或shutdown原因退出时。ps:Restart参数会覆盖主进程的restart strategy ,即子进程的重启规则设为temporary,主进程的启动规则设为one_for_all或rest_for_one,当主进程的某个其它子进程死掉会因为temporary而不会被重启
Shutdown这个参数用来设置子进程怎么被终止1、brutal_kill表示子进程被exit(Child, kill)无条件的终止;2、interger表示主进程会用信号exit(Child, shutdown)来通知子进程要终止并等待子进程的eixt信号,如果主进程在规矩的时间内(interger时间内)没收到子进程的信号,主进程会发送exit(Child, kill)无条件的杀死子进程;3、infinity如果子进程也是督程,那么该参数值应设为infinity,这样才能保证该子进程(supervisor)有足够的时间结束他的subtree(进程树)。ps:可选参数,如果子进程是worker,默认用5000,如果是supervisor,默认用infinity
Type标识该子进程是督程还是佣程,默认是worker
Module是有一个元素的列表[Module],假如子进程是supervisor、gen_server 或 gen_fsm,那么Module 是回调模块的名称;假如子进程是gen_event,那么Modules 应该是dynamic

* 重启策略(restart strategies)
1、 one_for_one, 默认的重启规则,意味着如果一个子进程挂掉了,只有该子进程会被重启,不会影响到其它子进程。
2、one_for_all, 如果有一个子进程挂掉了,所有其它子进程都会跟着挂掉,并且全部子进程重新启动。
3、rest_for_one,如果某个子进程挂掉,在它后面启动的子进程(根据首次启动顺序)都会跟着挂掉,并且该终止的进程和它后面的进程都会被重启。
4、simple_one_for_one, simple_one_for_one 重启规则的督程就是一个简化的 one_for_one 督程,有着该启动规则的督程,不会启动任何子进程,所有的子进程都必须由supervisor:start_child(Sup, List)动态添加,并且所有的子进程执行同一段代码(==因为后面添加的子进程不能再定义子规则即不能用supervisor:start_child(my_tcp, {start_child, {start_child, start_listen, []}, permanent, 5000, worker, [start_child]}).这样的方法start_child,只能通过supervisor:start_child(my_tcp, []).来start_child,并且child process必须返回{ok, Child},如果返回的是ignore,则不会往主进程中添加子进程==),其中List会被追加到{M, F, Args}中的Args中(即List ++ Args)作为参数,最终调用apply(M, F, [Args]++[List]).
* 最大重启频率(maximum restart intensity)
1、{one_for_one, MaxR, MaxT} ==> {one_for_one, 1, 60}, 在 MaxT的时间内重启次数超过MaxR次,这时它的子进程和它本身都会被终止。这个参数是为了避免子进程进入无限循环地终止和启动之中.
* supervisor:start_child(SupRef, ChildSpec).
1、 含义:动态的添加子规范(childspec)到监督器SupRef中,并启动相应的子进程,该子进程由父进程SupRef管理。ChildSpec必须是有效的子规范,(除非监督者是由simple_one_for_one启动策略启动的,见启动策略第四点),子进程由子规范定义的启动函数启动.
2、其中SupRef的值可以是:1)、pid; 2)、Name,如果监督者是当地注册的;3)、{Name,Node}, 如果监督者在当地另外一个节点(node)注册的;4)、{global,Name}, 如果监督者是全局(globally)注册的;5)、{via,Module,Name},还不了解.
3、如果已经存在具有指定标识符的子规范,则将ChildSpec丢弃,并且该函数返回{error,already_present} or {error,{already_started,Child}},这取决于相应的子进程是否正在运行.
4、如果子进程启动函数返回 {ok,Child} or {ok,Child,Info}, 则子规范和子进程id将加入监督者(supervisor)中,并且该方法(start_child)也返回一样的值.
5、如果子进程启动函数返回ignore,则子规范会被加入监督者(supervisor)中==(除非监督者是由simple_one_for_one启动策略启动的,如是,该函数会返回{ok,underfined}并且子进程和子规范都不会被加入到supervisor中)==,但是子进程id将会被设为underfined,该函数会返回{ok, underfined}.
* start_link(Module, Args) and start_link(SupName, Module, Args).
1、启动一个监督进程作为监督树的一部分,这监督进程调用Module:init/1去寻找重新启动策略、最大重新启动强度和子进程,确保同步启动,直到Module:init/1有返回并且所有子进程都启动成功start_link/2、3才会返回.
2、 SupName={local,Name}, SupName={global,Name}, SupName={via,Module,Name}, 如果没有提供SupName, 则该监督者不会被注册.
3、如果所有的子进程启动函数都返回{ok, Child},{ok, Child, Info} or ignore,那么该方法返回{ok, Pid}, 该Pid就是supervisor的pid.
4、如果该具有指定SupName的进程已经存在,那么该返回会返回{error,{already_started,Pid}}, 该Pid就是那个已经存在的进程的pid;如果Module:init/1返回ignore,那么supervisor会被正当的原因(normal)终止.
5、在启动子进程的过程中,如果任何一个子进程启动失败或者返回error tuple或者一个不正确的值,那么supervisor会立即终止其它已经启动的子进程,然后终止自己并且返回{error, {shutdown, Reason}}.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值