Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Erlang中生成数量可变的gen_服务器_Erlang - Fatal编程技术网

如何在Erlang中生成数量可变的gen_服务器

如何在Erlang中生成数量可变的gen_服务器,erlang,Erlang,目前,我正在使用lists:foreach和spawn_link为项目启动可变数量的工作人员,即启动时确定的工作人员数量。我希望每个worker都是genu服务器,这样我就可以调用其中的异步或同步消息genu server:cast等。这可能吗?是的,这可能 您可以使用简单的一对一: 一个简化的一对一管理器,其中所有子进程都是 动态添加相同流程类型的实例 下面是一个代码示例: master.erl是一名主管: -module(master). -behaviour(supervisor).

目前,我正在使用lists:foreach和spawn_link为项目启动可变数量的工作人员,即启动时确定的工作人员数量。我希望每个worker都是genu服务器,这样我就可以调用其中的异步或同步消息genu server:cast等。这可能吗?

是的,这可能

您可以使用简单的一对一:

一个简化的一对一管理器,其中所有子进程都是 动态添加相同流程类型的实例

下面是一个代码示例: master.erl是一名主管:

-module(master).

-behaviour(supervisor).

%% API
-export([start_link/0]).

%% Supervisor callbacks
-export([init/1]).

-define(SERVER, ?MODULE).

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

init([]) ->
    RestartStrategy = simple_one_for_one,
    MaxRestarts = 1000,
    MaxSecondsBetweenRestarts = 3600,

    SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts},

    Restart = permanent,
    Shutdown = 2000,
    Type = worker,

    AChild = {'worker', {'worker', start_link, []},
          Restart, Shutdown, Type, ['worker']},

    {ok, {SupFlags, [AChild]}}.
-module(my_sup).

-behaviour(supervisor).

%% API

-export([start_link/1]).

%% supervisor callbacks

-export([init/1]).

%% API

start_link(Argg) ->
    gen_server:start_link(?MODULE, Args).

%% supervisor callbacks

init(Args) ->
    Sup_flags = #{strategy => one_for_one, intensity => 1, period => 5},
    Child_specs = [ #{id => Id, start => MFA}
        || {Id, {_M, _F, _A} = MFA} <- Args ],
    {ok, {Sup_flags, Child_specs}}.
worker.erl是童工:

-module(worker).

-behaviour(gen_server).

%% API
-export([start_link/0]).
-export([start_link/1]).

%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
     terminate/2, code_change/3]).

-define(SERVER, ?MODULE). 

-record(state, {}).

start_link() ->
    gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
start_link(I) ->
    ServerName = lists:flatten(io_lib:format("~p~p", [?SERVER, I])),
    io:format("I am ~p~n", [list_to_atom(ServerName)]),
    gen_server:start_link({local, list_to_atom(ServerName)}, ?MODULE, [], []).

init([]) ->
    {ok, #state{}}.


handle_call(_Request, _From, State) ->
    Reply = ok,
    {reply, Reply, State}.

handle_cast(calc, State) ->
     io:format("result 2+2=4~n"),
     {noreply, State};
handle_cast(calcbad, State) ->
     io:format("result 1/0~n"),
     1 / 0,
     {noreply, State};
handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.


terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.
在erlang shell中:

22> master:start_link().                                                               
{ok,<0.2475.0>}
23> lists:map(fun(X) -> supervisor:start_child(master, [X]) end, lists:seq(1, 10)).
是的,这是可能的

您可以使用简单的一对一:

一个简化的一对一管理器,其中所有子进程都是 动态添加相同流程类型的实例

下面是一个代码示例: master.erl是一名主管:

-module(master).

-behaviour(supervisor).

%% API
-export([start_link/0]).

%% Supervisor callbacks
-export([init/1]).

-define(SERVER, ?MODULE).

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

init([]) ->
    RestartStrategy = simple_one_for_one,
    MaxRestarts = 1000,
    MaxSecondsBetweenRestarts = 3600,

    SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts},

    Restart = permanent,
    Shutdown = 2000,
    Type = worker,

    AChild = {'worker', {'worker', start_link, []},
          Restart, Shutdown, Type, ['worker']},

    {ok, {SupFlags, [AChild]}}.
-module(my_sup).

-behaviour(supervisor).

%% API

-export([start_link/1]).

%% supervisor callbacks

-export([init/1]).

%% API

start_link(Argg) ->
    gen_server:start_link(?MODULE, Args).

%% supervisor callbacks

init(Args) ->
    Sup_flags = #{strategy => one_for_one, intensity => 1, period => 5},
    Child_specs = [ #{id => Id, start => MFA}
        || {Id, {_M, _F, _A} = MFA} <- Args ],
    {ok, {Sup_flags, Child_specs}}.
worker.erl是童工:

-module(worker).

-behaviour(gen_server).

%% API
-export([start_link/0]).
-export([start_link/1]).

%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
     terminate/2, code_change/3]).

-define(SERVER, ?MODULE). 

-record(state, {}).

start_link() ->
    gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
start_link(I) ->
    ServerName = lists:flatten(io_lib:format("~p~p", [?SERVER, I])),
    io:format("I am ~p~n", [list_to_atom(ServerName)]),
    gen_server:start_link({local, list_to_atom(ServerName)}, ?MODULE, [], []).

init([]) ->
    {ok, #state{}}.


handle_call(_Request, _From, State) ->
    Reply = ok,
    {reply, Reply, State}.

handle_cast(calc, State) ->
     io:format("result 2+2=4~n"),
     {noreply, State};
handle_cast(calcbad, State) ->
     io:format("result 1/0~n"),
     1 / 0,
     {noreply, State};
handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.


terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.
在erlang shell中:

22> master:start_link().                                                               
{ok,<0.2475.0>}
23> lists:map(fun(X) -> supervisor:start_child(master, [X]) end, lists:seq(1, 10)).

没有任何东西阻止您调用我的\u工作者:启动\u链接而不是生成\u链接

在职工人

-module(my_worker).

-behaviour(gen_server).

%% API

-export([start_link/1]).

%% gen_server callbacks

-export([init/1, ...]).

%% API

start_link(Arg) ->
    gen_server:start_link(?MODULE, Arg, []).

%% gen_server callbacks

init(Arg) ->
    ...
然后你就可以启动它了

[ {ok, _Pid} = my_worker:start_link(Arg) || Arg <- Args ].
如果你想让他们接受监督:

-module(master).

-behaviour(supervisor).

%% API
-export([start_link/0]).

%% Supervisor callbacks
-export([init/1]).

-define(SERVER, ?MODULE).

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

init([]) ->
    RestartStrategy = simple_one_for_one,
    MaxRestarts = 1000,
    MaxSecondsBetweenRestarts = 3600,

    SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts},

    Restart = permanent,
    Shutdown = 2000,
    Type = worker,

    AChild = {'worker', {'worker', start_link, []},
          Restart, Shutdown, Type, ['worker']},

    {ok, {SupFlags, [AChild]}}.
-module(my_sup).

-behaviour(supervisor).

%% API

-export([start_link/1]).

%% supervisor callbacks

-export([init/1]).

%% API

start_link(Argg) ->
    gen_server:start_link(?MODULE, Args).

%% supervisor callbacks

init(Args) ->
    Sup_flags = #{strategy => one_for_one, intensity => 1, period => 5},
    Child_specs = [ #{id => Id, start => MFA}
        || {Id, {_M, _F, _A} = MFA} <- Args ],
    {ok, {Sup_flags, Child_specs}}.

您可以从应用程序中读取它们的配置:get_env/1、2、3或数据库或其他任何内容。您可以在之后使用supervisor:start\u child/2启动它们。你可以用简单的一对一等等。这只是一个过程。

没有任何东西阻止您调用我的工作程序:启动链接而不是生成链接

在职工人

-module(my_worker).

-behaviour(gen_server).

%% API

-export([start_link/1]).

%% gen_server callbacks

-export([init/1, ...]).

%% API

start_link(Arg) ->
    gen_server:start_link(?MODULE, Arg, []).

%% gen_server callbacks

init(Arg) ->
    ...
然后你就可以启动它了

[ {ok, _Pid} = my_worker:start_link(Arg) || Arg <- Args ].
如果你想让他们接受监督:

-module(master).

-behaviour(supervisor).

%% API
-export([start_link/0]).

%% Supervisor callbacks
-export([init/1]).

-define(SERVER, ?MODULE).

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

init([]) ->
    RestartStrategy = simple_one_for_one,
    MaxRestarts = 1000,
    MaxSecondsBetweenRestarts = 3600,

    SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts},

    Restart = permanent,
    Shutdown = 2000,
    Type = worker,

    AChild = {'worker', {'worker', start_link, []},
          Restart, Shutdown, Type, ['worker']},

    {ok, {SupFlags, [AChild]}}.
-module(my_sup).

-behaviour(supervisor).

%% API

-export([start_link/1]).

%% supervisor callbacks

-export([init/1]).

%% API

start_link(Argg) ->
    gen_server:start_link(?MODULE, Args).

%% supervisor callbacks

init(Args) ->
    Sup_flags = #{strategy => one_for_one, intensity => 1, period => 5},
    Child_specs = [ #{id => Id, start => MFA}
        || {Id, {_M, _F, _A} = MFA} <- Args ],
    {ok, {Sup_flags, Child_specs}}.

您可以从应用程序中读取它们的配置:get_env/1、2、3或数据库或其他任何内容。您可以在之后使用supervisor:start\u child/2启动它们。你可以用简单的一对一等等。这只是一个过程。

看起来不错,但我如何让主管启动孩子跑步?看起来不错,但我如何让主管启动孩子跑步?