按照迈克尔的建议,我也会去监督。
您可以在gen_server:start_link 中使用{via,Module,ViaName} 来使用除atoms 之外的其他名称。详情见这里:http://erlang.org/doc/man/gen_server.html#start_link-4
例如,gproc
gen_server:start_link({via, gproc, {n, l, {?MODULE, Name}}, ?MODULE, [], []).
在调用 gen_server 时不要忘记使用相同的 {via, gproc, ...} 结构,而不仅仅是使用 Name:
gen_server:call({via, gproc, {n, l, {?MODULE, Name}}, {execute_command, Command}).
我倾向于这样定义via:
-define(SERVER(Name), {via, gproc, {n, l, {?MODULE, Name}}}).
然后像这样使用它:
gen_server:start_link(?SERVER("Testing"), ?MODULE, [], []).
gen_server:call(?SERVER("Testing"), {execute_command, Command}).
然后您可以在具有 simple_one_for_one 策略和 temporary 子规范的主管中启动它,如下所示:
主管
-module(my_cool_sup).
-behaviour(supervisor).
%% API
-export([start_link/1, start_child/1]).
%% Supervisor callbacks
-export([init/1]).
-define(SERVER, ?MODULE).
%% Helper macro for declaring children of supervisor
-define(CHILD(ChildName, Type, Args), {ChildName, {ChildName, start_link, Args}, temporary, 5000, Type, [ChildName]}).
%%====================================================================
%% API functions
%%====================================================================
start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
start_child(Name) ->
supervisor:start_child(?SERVER, [Name]).
%%====================================================================
%% Supervisor callbacks
%%====================================================================
init([]) ->
RestartStrategy = {simple_one_for_one, 1, 5},
Children = [?CHILD(my_cool_server, worker, [])],
{ok, { RestartStrategy, Children} }.
gen_server
-module(my_cool_server).
-behavior(gen_server).
%% API
-export([start_link/3, execute_command/3]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-define(SERVER(Name), {via, gproc, {n, l, {?MODULE, Name}}}).
%%%===================================================================
%%% API
%%%===================================================================
start_link(Name) ->
gen_server:start_link(?SERVER(Name), ?MODULE, [], []).
execute_command(Name, Command) ->
gen_server:call(?SERVER(Name), {execute_command, Command}).
%%%===================================================================
%%% gen_server callbacks
%%%===================================================================
%% Your normal gen_server callbacks here...
现在您可以使用my_cool_sup:start_child("My cool name"). 来启动您的子进程。他们将受到监督,如果他们已经开始,它将返回already_started,但不会引发错误。
查看start_child了解更多详情:http://erlang.org/doc/man/supervisor.html#start_child-2