gen_tcp:connect 将在使用 supervisor 时关闭
Posted
技术标签:
【中文标题】gen_tcp:connect 将在使用 supervisor 时关闭【英文标题】:gen_tcp:connect will close when using supervisor 【发布时间】:2021-03-02 13:29:36 【问题描述】:当我直接运行 gen_server 时,我有一个连接到 tcp 端口的简单 gen_server:
erl -noshell -s ttest start
它工作正常,但是当我运行时:
erl -noshell -s tt_sup start_link
连接将立即关闭,如果我取消与主管的链接,它将起作用:
erl -noshell -s tt_sup start_shell
如何使用主管运行我的简单 gen_tcp:connect (gen_server)?
主管:
-module(tt_sup).
-behaviour(supervisor).
-export([init/1, start_link/0, start_shell/0]).
start_link() ->
io:format("Supervisor started with PID~p~n", [self()]),
ok, Pid = supervisor:start_link(tt_sup, []),
io:format("Supervisor PID=~p~n", [Pid]),
ok, Pid.
start_shell() ->
io:format("Supervisor started with PID~p~n", [self()]),
ok, Pid = supervisor:start_link(tt_sup, []),
io:format("Supervisor PID=~p~n", [Pid]),
unlink(Pid),
ok, Pid.
init(_Args) ->
SupFlags = #strategy => one_for_one,
Child = [#id => ttest, start => ttest, start, [],
restart => permanent, shutdown => brutal_kill,
type => worker, modules => [ttest]],
ok, SupFlags, Child.
gen_server:
-module(ttest).
-export([start/0,init/1,handle_cast/2,handle_call/3,handle_info/2,terminate/2,connect/1]).
-behaviour(gen_server).
start() ->
io:format("gen_server start id is ~p~n",[self()]),
ok,Pid = gen_server:start_link(local,ttest,ttest,[],[]),
io:format("gen_server id is ~p~n",[Pid]),
connect(Pid),
ok,Pid.
init(_Args) ->
io:format("init id is ~p~n",[self()]),
ok,[].
handle_call(tcp,Socket,Bin,_From,States) ->
reply,States,States.
handle_info(tcp,Socket,Bin,States) ->
io:format("got info msg"),
noreply,States.
handle_cast(send,Msg,States) ->
reply,States.
connect(I) ->
io:format("connect id is ~p~n",[self()]),
ok,Socket =gen_tcp:connect("localhost",6000,[binary,active,true]),
gen_tcp:controlling_process(Socket,I).
terminate(shutdown, State) ->
io:format("terminating"),
ok.
【问题讨论】:
【参考方案1】:运行-s
的进程在没有更多代码要执行时以normal
退出。主管接收到该信号,由于它来自其父级,因此它退出(不管它是 normal
),如 gen_server:terminate/2 中所述(supervisor
s 是 gen_server
s 和 trap_exit
活动):
即使 gen_server 进程不是监督树的一部分,如果它从其父进程接收到“退出”消息,也会调用此函数。原因与“退出”消息中的相同。
我没有测试过你的代码,但是如果你在你的gen_server
中添加一个process_flag(trap_exit, true)
,你肯定会复制这种行为。
【讨论】:
是的,如果我将process_flag(trap_exit, true)
添加到gen_server init,也会一样,我应该如何启动supervisor?
@Geo-7 如果你想创建一个具有适当 OTP 监督树的生产级项目,你应该使用它创建一个应用程序和一个发布,检查 learnyousomeerlang.com/… 和 learnyousomeerlang.com/release-is-the-word (learnyousomeerlang是极好的参考)。如果你想让它尽快运行,只需在tt_sup:start_link
返回之前添加一个timer:sleep(infinity)
以上是关于gen_tcp:connect 将在使用 supervisor 时关闭的主要内容,如果未能解决你的问题,请参考以下文章
erlang/elixir gen_tcp connect - 不连接但telnet wil
sh Magento SUPEE-9767 Checkout表格主题补丁
Android java.lang.NoSuchFieldError: No static field xxx of type I in class Lcom/XX/R$id; or its supe