zoukankan      html  css  js  c++  java
  • erlang supervisor simple_one_for_one实例

    simple_one_for_one vs one_for_one:

    相同点:

    这种Restart Strategy和one_for_one基本相同(即当一个child process挂掉后,仅仅重启该child process 而不影响其他child process)。

    异同点:

    1, simple_one_for_one supvisor启动时不会启动任何子进程,所有子进程都只能通过调用 supervisor:start_child(Sup, Args) 来动态启动。

    2, simple_one_for_one supvisor持有child process的定义,并有一个dict存放数据, 其实就是如干个child process,共享一份数据。

    3, 一个simple_one_for_one supervisor只有一个(single)simple_one_for_one的定义, 也就是说它只能生产出一种类型worker process。

    supervisor:start_child(Sup, Args) :

        Sup:  Supervisor的Pid或者registered Name.

        Args: 当supervisor的类型是simple_one_for_one时,Args会追加到spec的参数中。

    例如:

    -module(simple_sup).
    -behaviour(supervisor).
    
    -export([start_link/0]).
    -export([init/1]).
    
    start_link() ->
        supervisor:start_link({local,?MODULE}, ?MODULE, []).
    
    init(_Args) ->
      {M, F, A} = _Args,
        {ok, {{simple_one_for_one, 0, 1},
              [{M, {M, F, A},
                temporary, brutal_kill, worker, [M]}]}}.

    调用supervisor:start_child(simple_sup, Args)后,最终启动子进程的代码会是:apply(M, F, A++Args).

    调用supervisor:start_child(Sup, Args)可能会遇到的错误:

    1, noproc: 可能的原因是在调用supervisor:start_link时没写参数{local, ?MODULE},即上面代码红色部分,此时进程Sup并不存在,所以会产生

                     noproc错误。

    2,undef: 可能的原因是A++Args后,与child process的start_link函数参数不一致。

    实例代码:

         实例包含两部分,一是监控普通进程(normal_process.erl),二是监控gen_server进程(gen_server_process.erl)。

    common.hrl

    %%-define(CALL, normal_process).
    -define(CALL, gen_server_process).

    simple_sup.erl

    -module(simple_sup).
    -behaviour(supervisor).
    
    -export([start_link/0]).
    -export([init/1]).
    
    -include("common.hrl").
    
    start_link() ->
        supervisor:start_link({local, ?MODULE}, simple_sup, []).
    
    init(_Args) ->
        {ok, {{simple_one_for_one, 0, 1}, 
              [{?CALL, {?CALL, start_link, []},
              temporary, brutal_kill, worker, [?CALL]}]}}.

    normal_process.erl

    -module(normal_process).
    
    -export([start_link/0, start_loop/1]).
    
    start_link() ->
        proc_lib:start_link(?MODULE, start_loop, [self()]).
    
    start_loop(Parent) ->
        proc_lib:init_ack(Parent, {ok, self()}),
        loop().
    
    loop() ->
        receive
            Args ->
                io:format("~p~n", [Args])
        end.

    gen_server_process.erl

    -module(gen_server_process).
    -behaviour(gen_server).
    -export([start_link/0]).
    
    %% gen_server callbacks
    -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
             terminate/2, code_change/3]).
    
    %% interface
    -export([start/0, stop/0, echo/1]).
    
    %% interface implement
    start()      -> start_link().
    stop()       -> gen_server:call(?MODULE, stop).
    echo(String) -> gen_server:call(?MODULE, {echo, String}).
    
    %% gen_server callbacks implement
    start_link() -> gen_server:start_link({local,?MODULE}, ?MODULE, [], []).
    
    init([]) ->
        {ok, 0}. 
    
    handle_call({echo, String}, _From, Tab) ->  
        Reply = String,
        {reply, Reply, Tab};
    
    handle_call(stop, _From, Tab) ->
        {stop, normal, stopped, Tab}.
    
    handle_cast(_Msg, State) -> {noreply, State}.
    handle_info(_Info, State) -> {noreply, State}.
    terminate(_Reason, _State) -> ok. 
    code_change(_OldVsn, State, _Extra) -> {ok, State}.

    编译命令

    c(simple_sup).
    c(normal_process).
    c(gen_server_process).

    测试命令:

    simple_sup:start_link().
    supervisor:start_child(simple_sup, []).

    测试通过start_child启动普通进程:

    修改common.hrl:-define(CALL, normal_process). 执行编译命令 + 测试命令

    测试通过start_child启动gen_server进程:

    修改common.hrl:-define(CALL, gen_server_process). 执行编译命令 + 测试命令

  • 相关阅读:
    CodeSmith实用技巧(十四):使用Progress对象
    .NET设计模式(5):工厂方法模式(Factory Method)
    CodeSmith实用技巧(七):从父模版拷贝属性
    CodeSmith实用技巧(十一):添加设计器的支持
    CodeSmith实用技巧(六):使用XML 属性
    CodeSmith实用技巧(三):使用FileDialogAttribute
    CodeSmith实用技巧(十二):自动执行SQL脚本
    CodeSmith中实现选择表字段的几点想法
    CodeSmith开发系列资料总结
    你真的了解.NET中的String吗?
  • 原文地址:https://www.cnblogs.com/little-ant/p/3196201.html
Copyright © 2011-2022 走看看