我已经建立了一个符合OTP标准的应用程序,我有一个gen_server和一个主管。我也有一个脚本来启动它们。
我的脚本包含这样的内容。 erl -pa module_name / ebin -name abc @ hostname -setcookie test -s module_sup start_link()
这不会启动主管。但是当我在shell中执行module_sup:start_link()时,它可以工作。
当我这样做的时候 erl -pa module_name / ebin -name abc @ hostname -setcookie test -s module_srv start_link() 即没有主管的服务器,服务器就会启动。
那么,我在这里做错了什么。我们不允许以这种方式启动主管。
任何帮助都会受到高度关注。
感谢名单, 威尔逊
答案 0 :(得分:5)
supervisor:start_link/2
创建一个指向其调用进程的链接。当调用进程退出时,主管将被取消。
erl -s module_sup start_link
正在启动主管,但它被终止,因为你的启动函数在它自己的进程内运行,一旦函数退出就会死掉。
您可以观察到主管开始spawn(module_sup, start_link, []).
的类似行为并立即被杀死。当您手动启动主管时,调用进程就是shell。当shell退出时,它会杀死主管。
通常,顶层主管应由应用程序启动。
答案 1 :(得分:0)
这与How do I start applications by command line as a daemon?非常相似。简而言之,除非使用unlink/1
,否则不能使用-s来启动主管,这是一个完全的问题。花在学习如何将代码打包为application上的时间更长。我建议用rebar执行此操作。
答案 2 :(得分:0)
重要的是要注意,如果链接进程以“正常”以外的原因终止,则进程才会终止,这意味着只是完成其执行的进程不会终止与其链接的进程。 (来源http://www.erlang.org/doc/reference_manual/processes.html#id204170) 我认为这是Erlang的一个重要方面,不应该被误解。
以下源代码显示了这一点:
1> spawn(
1> fun() ->
1> io:format("outer ~p~n", [self()]),
1> spawn_link(
1> fun () ->
1> io:format("inner ~p~n", [self()]),
1> receive
1> Msg -> io:format("received ~p~n", [Msg])
1> end
1> end)
1> end).
outer <0.37.0>
<0.37.0>
inner <0.38.0>
2> is_process_alive(pid(0,37,0)).
false
3> pid(0,38,0) ! test.
received test
test
4>
您可以看到来电者<0.37.0&gt;没有运行,但是过程&lt; 0.38.0&gt;仍在那里,等待消息。
无论如何,当主管终止出口信号时,主叫方将不会终止。当然,除非它被编程为这样做。但是我检查了源代码并且找不到这个,但是唉,我的分析可能太肤浅了。
你有运气吗?我会尝试进行一些测试,看看能否弄清楚发生了什么。