练习要求
制作一个名为prime_tester_server的gen_server,让它测试给定的数字是否是质数。
你可以使用lib_primes.erl里的is_prime/2函数来处理(或者自己实现一个更好的质数测试函
数)。把它添加到sellaprime_supervisor.erl的监控树里。
质数判断server实现
-module(prime_tester_server).
-behaviour(gen_server).
-export([start_link/0]).
-export([test_prime/1]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
%% 初始化
init(_Args) ->
{ok, []}.
%% 处理调用请求
handle_call({test_prime, Number}, _From, State) ->
is_prime(Number),
{reply, {ok, is_prime(Number)}, State}.
%% 处理消息投递
handle_cast(_Msg, State) ->
{noreply, State}.
%% 处理信息
handle_info(_Info, State) ->
{noreply, State}.
%% 终止回调
terminate(_Reason, _ServerState) ->
ok.
%% 版本变更回调
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%% 启动服务器
start_link() ->
gen_server:start_link({local, prime_tester_server}, ?MODULE, [], []).
%% 测试质数
test_prime(Number) ->
gen_server:call(prime_tester_server, {test_prime, Number}).
%% 质数检测函数
is_prime(Number) when Number < 2 -> false;
is_prime(2) -> true;
is_prime(Number) ->
lists:all(fun(X) -> Number rem X =/= 0 end, lists:seq(2, trunc(math:sqrt(Number)))).
监控树实现
-module(sellaprime_supervisor).
-behaviour(supervisor).
-export([start_link/0, init/1]).
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init(_) ->
ChildSpecs = [
% 添加 prime_tester_server 到监督树
{tag1,
{prime_tester_server, start_link, []},
permanent,
10000,
worker,
[prime_tester_server]}
],
{ok, {{one_for_one, 5, 10}, ChildSpecs}}.
测试结果
能够正常启动监控树与服务器,但是在进行报错测试后,之后服务器没有正常重启
-module(sellaprime_supervisor).
-behaviour(supervisor).
-export([start_link/1, init/1,test/0]).
test() ->
{ok, Pid} = supervisor:start_link({local, ?MODULE}, ?MODULE, _Arg = []),
unlink(Pid).
start_link(Args) ->
supervisor:start_link({local, ?MODULE}, ?MODULE, Args).
init(_) ->
ChildSpecs = [
% 添加 prime_tester_server 到监督树
{prime_tester_server,
{prime_tester_server, start_link, []},
permanent,
10000,
worker,
[prime_tester_server]}
],
{ok, {{one_for_one, 5, 10}, ChildSpecs}}.
查找了很久,需要在监控树中进行unlink(Pid)操作才行
修改后就能重启了,与预期相符