标签:
1 child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules} 2 Id = term() 3 StartFunc = {M,F,A} 4 M = F = atom() 5 A = [term()] 6 Restart = permanent | transient | temporary 7 Shutdown = brutal_kill | int()>0 | infinity 8 Type = worker | supervisor 9 Modules = [Module] | dynamic 10 Module = atom()
Shutdown:关闭时间
Type:子进程的类型 worker | supervisor
Modules : 回调模块
如果子进程是supervisor、gen_server、gen_fsm则Modules是回调模块name的列表,如果为gen_event则为dynamic。(未验证)
1 -module(add_sup). 2 3 -behaviour(supervisor). 4 5 -export([start_link/0, start_child/0]). 6 -export([init/1]). 7 8 -define(SERVER, ?MODULE). 9 10 start_link() -> 11 supervisor:start_link({local, ?SERVER}, ?MODULE, []). 12 start_child() -> 13 supervisor:start_child(?MODULE, []). 14 15 init([]) -> 16 RestartStrategy = simple_one_for_one, 17 MaxRestarts = 2, 18 MaxSecondsBetweenRestarts = 100, 19 20 SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts}, 21 22 Restart = permanent, 23 Shutdown = 20000, 24 Type = worker, 25 26 AChild = {add2, {add2, start_link, []}, 27 Restart, Shutdown, Type, [add2]}, 28 29 {ok, {SupFlags, [AChild]}}.
通过调用start_child/0来动态的加入子进程。
1 start_link() -> 2 gen_server:start_link(?MODULE, [], []).
普通子进程代码:
1 -module(common). 2 -author("Administrator"). 3 4 -export([start_link/0, start_loop/2]). 5 6 start_link() -> 7 Res = proc_lib:start_link(?MODULE, start_loop, [self(), ?MODULE]), %%启动一个普通进程 8 Res. 9 10 start_loop(Parent,Name) -> 11 register(Name, self()), %%给普通进程命名,否则默认是pid()。 12 proc_lib:init_ack(Parent, {ok, self()}), 13 loop(). 14 15 loop()-> 16 receive 17 Args -> 18 io:format("args:~p~n",[Args]) 19 end.
1 {common, {common, start_link, []}, permanent, 10000, worker, [common]}
普通子进程的终止与重启:
对于监控树A的一个子进程是另一颗监控树B,监控树B有多个动态加入的子进程,若B重启后那么动态加入的子进程将不复存在,若B重启后需要想重新加入这些子进程,一、记录动态加入子进程的信息,当监控树重启后再动态加入以前的子进程;二、改进supervisor的实现,可以重启动态加入的子进程(未实践,rabbitmq中对supervisor修改来实现这个功能)。
1 init([]) -> 2 {ok, ets:new(proc_ets,[duplicate_bag, public, named_table, {keypos,1}])}.
当前监控树
2.动态加入子进程,并记录信息;重启子监控树,并动态加入子进程
1 -module(add_sup). 2 -include("ets_arg.hrl"). 3 -behaviour(supervisor). 4 5 -export([start_link/0, start_child/1]). 6 -export([init/1]). 7 8 -define(SERVER, ?MODULE). 9 10 -spec(start_link() -> 11 {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). 12 start_link() -> 13 {ok, Pid} = supervisor:start_link({local, ?SERVER}, ?MODULE, []), 14 case ets:lookup(?ETS, ?MODULE) of 15 Object -> load_dynamic_proc(Object) %% 动态的加入存储的子进程 16 end, 17 {ok, Pid}. 18 19 start_child(_Type) -> 20 {ok, Pid} = supervisor:start_child(?MODULE, []), 21 case _Type of 22 restart -> ok; 23 _->ets:insert(?ETS,{?MODULE, ?SIMPLE, []}) %% 存储动态加入子进程的信息 24 end, 25 {ok, Pid}. 26 27 init([]) -> 28 RestartStrategy = simple_one_for_one, 29 MaxRestarts = 2, 30 MaxSecondsBetweenRestarts = 100, 31 32 SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts}, 33 34 Restart = permanent, 35 Shutdown = brutal_kill, 36 Type = worker, 37 38 AChild = {add2, {add2, start_link, []}, 39 Restart, Shutdown, Type, [add2]}, 40 41 {ok, {SupFlags, [AChild]}}. 42 43 load_dynamic_proc([])-> 44 ok; 45 load_dynamic_proc([H|T]) -> 46 start_child(restart), 47 load_dynamic_proc(T), 48 {ok, H}.
标签:
原文地址:http://www.cnblogs.com/liuweiccy/p/4622075.html