服务器进程超时
我必须实施erlang gen_server进程,这些进程已经存在了好几个小时。 但超时后gen_server进程应该被终止。 这些过程是动态启动的,因此使用动态监督。 这个想法是在进程init上使用timer:apply_after()。 所以gen_server进程的init看起来就像那样
init(Time) ->
timer:apply_after(Time, my_supervisor, kill_child, [self()]),
% do other init things
ok.
我对erlang有点新,所以问题是这种方法是好的还是有一些缺点? 有更好的解决方案吗?
谢谢!
我会做一些不同的事情:
init([]) ->
erlang:send_after(Time, self(), timeout_shutdown),
{ok, #state{}}.
handle_info(timeout_shutdown, State) ->
{stop, normal, State};
...
通过这种方式,流程可以优雅地关闭,而无需主管杀死它。 更好的是,你可以在监督者中声明孩子为transient
的,所以它不会重新启动。
您可能需要考虑使用erlang:send_after / 3并使用handle_info对gen_server中的消息作出反应:
使用erlang创建计时器:send_after / 3和erlang:start_timer / 3比使用计时器模块提供的计时器高效得多。 定时器模块使用单独的进程来管理定时器,并且如果许多进程频繁地创建和取消定时器(特别是在使用SMP模拟器时),则该进程可能很容易变得过载。
定时器模块中不管理定时器的功能(如定时器:tc / 3或定时器:睡眠/ 1)不会调用定时器服务器进程,因此无害。
http://www.erlang.org/doc/efficiency_guide/commoncaveats.html
你可以尝试下面的代码:进程worker1
关闭一次,进程worker2
每worker2
关闭一次。 你只需要加载两个梁,然后运行super:start_link(). super:main().
super:start_link(). super:main().
在erl shell中。
这是supervosor:
-module(super).
-behaviour(supervisor).
%% API
-export([start_link/0]).
-export([stop/0]).
-export([main/]).
%% 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]}}.
main() ->
add_worker(worker1, 1000),
add_worker(worker2, 2000).
add_worker(WorkerName, Time) when is_atom(WorkerName)->
supervisor:start_child(?SERVER, [WorkerName, Time]).
stop() ->
exit(whereis(?SERVER), shutdown).
这是gen_server:
-module(worker).
-behaviour(gen_server).
%% API
-export([start_link/2]).
%% 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(WorkerName, Time) ->
io:format("server: ~p start!~n", [WorkerName]),
gen_server:start_link({local, WorkerName}, ?MODULE, [WorkerName, Time], []).
init([WorkerName, Time]) ->
erlang:send_after(Time, self(), {WorkerName, timeout_shutdown}),
{ok, #state{}}.
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info({WorkerName, timeout_shutdown}, State) ->
io:format("server: ~p timeout_shutdown!~n", [WorkerName]),
{stop, normal, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
链接地址: http://www.djcxy.com/p/38247.html