Erlang之supervisor入门

1.概念:

     supervisor是OTP框架四大行为之一,它用于监视别的进程,当一个进程崩溃是,它能够快速重启该进程,并根据不同的策略做出不同的行为。

2.常用函数:

1.start_link({local/global,NAME}, MODULE, Args).

    创建一个supervisor的进程服务器,local为本地进程,global为全局进程,NAME为该进程名,MODULE为回调模块,调用该MODULE的init([])函数,Args为init的参数列表。

2.init([]) -> Result.

         1.  Result格式为:{ok,{SupFlags,[ChildSpec]}} | ignore,SupFlags通常为形式为{How, Max, Within}:在多长时间内(Within)重启了几次(Max),如何重启(HOW 重启策略);设计最大重启频率是为了避免反复重启进入死循环,一旦超出了此阈值,supervisor进程会结束掉自己以及它所有的子进程,并通过进程树传递退出消息,更上层的supervisor就会采取适当的措施,要么重启终止的supervisor要么自己也终止掉.

        2. How通常有以下几种格式:

           one_for_one : 若一个子进程崩溃,马上把他重启。
           one_for_all : 如果子进程终止,所有其它子进程也都会被终止,然后所有进程都会被重启.
           rest_for_one:如果一个子进程终止,在这个进程启动之后启动的进程都会被终止掉.然后终止掉的进程和连带关闭的进程都会被重启.

       3.ChildSpec为添加的子进程列表,格式会在start_child说明。

3.start_child(SupRef, ChildSpec) -> startchild_ret()

       1.SupRef为supervisor的进程名,ChildSpec为要添加并开启的子服务器。

       2.ChildSpec格式如下:

        

            1.Tag
                   这是一个原子类型的标签,将来可以用它指代工作进程(如果有必要的话)。
            2.{Mod, Func, ArgList}
                  它定义了监控器用于启动工作器的函数,将被用作 apply(Mod, Fun, ArgList) 的参数。
           3.Restart = permanent | transient | temporary
                   permanent (永久)进程总是会被重启。 transient (过渡)进程只有在以非正常退出值
              终止时才会被重启。 temporary (临时)进程不会被重启。
           4.Shutdown
                  这是关闭时间,也就是工作器终止过程允许耗费的最长时间。如果超过这个时间,工作
             进程就会被杀掉。(还有其他值可用,参见 supervisor 的手册页。)
          5.Type = worker | supervisor
                 这是被监控进程的类型。可以用监控进程代替工作进程来构建一个由监控器组成的树。
          6.[Mod1]
                如果子进程是监控器或者 gen_server 行为的回调模块,就在这里指定回调模块名。

4.restart_child(SupRef, Id) -> Result

    重启名为SupRef服务器中Pid为Id的子进程。

5.delete_child(SupRef, Id) -> Result

   删除该子进程,但前提必须得停止该进程。

6.terminate_child(SupRef, Id) -> Result

  停止该子进程

常用就着几个。

3.小例子

   mysupervisor.erl

-module(mysupervisor).
-compile(export_all).
-behavior(supervisor).

init([]) ->
    {ok, {{one_for_all, 10, 10}, []}}.

myserver.erl

-module(myserver).
-behavior(gen_server).
-compile(export_all).

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

init([]) ->
	ID = ets:new(pp,[set]),
	{ok,ID}.

add_man(Key,Value) ->
	gen_server:call(?MODULE,{add, Key, Value}).

delete_man(Key) ->
	gen_server:call(?MODULE,{del,Key}).

query_man(Key) ->
	gen_server:call(?MODULE,{qu,Key}).

handle_call({add, Key, Value}, _From, State) ->
	ets:insert(State,{Key, Value}),
	{reply,{ok,successs},State};

handle_call({del,Key}, _From, State) ->
	Reply = case ets:lookup(State,Key) of
		 		[] -> {no_the_man};
		 		_ -> {del_the_man}
			end,
	{reply, Reply, State};

handle_call({qu,Key}, _From, State) ->
	Reply = case ets:lookup(State, Key) of
		        [] -> {no_the_man};
		        Value -> {Key, Value}
			end,
	{reply, Reply, State}.
	

 

发布了133 篇原创文章 · 获赞 8 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/fbher/article/details/93209407