gpt4 book ai didi

Erlang gen_server : How to catch Errors?

转载 作者:行者123 更新时间:2023-12-02 04:23:16 25 4
gpt4 key购买 nike

我是 Erlang 开发新手,对进程关系感兴趣。

如果我们使用 process_flag(trap_exit, true) 链接两个进程 P1 和 P2 并使用类似 Pid 的构造! msgreceive .. after .. end - 第二个进程 P2 可以捕获像 badarith 这样的 P1 错误。

但是,如果我们使用与 P2 链接的 gen_server 进程 P1,则 P1 将在 P2 失败后终止。

那么,如何使用 gen_server 捕获 exit() 错误?

提前致谢!

附注测试代码。

P1:

-module(test1).
-compile(export_all).
-behaviour(gen_server).

start() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

init([]) -> Link = self(),
spawn(fun() ->
process_flag(trap_exit, true),
link(Link),
test2:start(Link)
end),
{ok, "lol"}.

handle_call(stop, From, State) ->
io:fwrite("Stop from ~p. State = ~p~n",[From, State]),
{stop, normal, "stopped", State};

handle_call(MSG, From, State) ->
io:fwrite("MSG ~p from ~p. State = ~p~n",[MSG, From, State]),
{reply, "okay", State}.

handle_info(Info, State) -> io:fwrite("Info message ~p. State = ~p~n",[Info, State]), {noreply, State}.

terminate(Reason, State) -> io:fwrite("Reason ~p. State ~p~n",[Reason, State]), ok.

P2:

-module(test2).
-compile(export_all).

start(Mod) ->
io:fwrite("test2: Im starting with Pid=~p~n",[self()]),
receiver(Mod).

receiver(Mod)->
receive
stop ->
Mod ! {goodbye},
io:fwrite("Pid: I exit~n"),
exit(badarith);
X ->
io:fwrite("Pid: I received ~p~n",[X])
end.

结果:test2 退出并出现 badarith 后,test1 进程失败。

38> 
38> c(test1).
test1.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,test1}
39> c(test2).
test2.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,test2}
40> test1:start().
test2: Im starting with Pid=<0.200.0>
{ok,<0.199.0>}
41> <0.200.0> ! stop.
Pid: I exit
Info message {goodbye}. State = "lol"
stop
** exception exit: badarith
42> gen_server:call(test1, stop).
** exception exit: {noproc,{gen_server,call,[test1,stop]}}
in function gen_server:call/2 (gen_server.erl, line 215)
43>

最佳答案

链接是双向的,但捕获导出不是;您需要调用process_flag(trap_exit, true)在 P1 中(您当前的代码在 P2 中执行此操作),然后处理 {'EXIT', FromPid, Reason} 形式的消息在handle_info (将P2的pid放入State以提供帮助)。

在这种情况下,如果 P1 停止,P2 停止是有意义的,否则我建议使用 monitor而不是链接。

旁注:

  1. 使用spawn_link而不是spawn + link .

  2. 移动风格更好spawn进入test2:start .

关于Erlang gen_server : How to catch Errors?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54841248/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com