【问题标题】:Erlang process: normal exit ignored by linked process, exits after "compiled twice"Erlang进程:链接进程忽略正常退出,“编译两次”后退出
【发布时间】:2014-09-04 10:46:21
【问题描述】:

在 Erlang 中,我创建了 2 个相互关联的进程。如果我从一个进程退出,那么如果正常退出,另一个进程会忽略它。这种行为可以在a link 中看到。

我的问题是,在两次编译相同的代码时,我可以看到第二个进程也退出了。这是我的示例代码:

-module(exitnormal).
-export([f1/0]).

f1() ->
    X = whereis(f2) =/= undefined,
    if
        X -> exit( whereis(f2), shutdown ), timer:sleep(1);
        true -> ""
    end,
    register( f2, spawn_link( fun() -> f2() end )),
    receive
        kill -> { ok, f1 }
    end.

f2() ->
    receive
        kill -> { ok, f2 }
    end.

我运行它得到以下结果:

1> c(exitnormal).
{ok,exitnormal}
2> erlang:register( f1, spawn( exitnormal, f1, [] )).
true
3> whereis(f2) ! kill, ok.
ok
4> whereis(f2).
undefined
5> whereis(f1).
<0.40.0>
6> c(exitnormal).
{ok,exitnormal}
7> whereis(f1).
<0.40.0>
8> c(exitnormal).
{ok,exitnormal}
9> whereis(f1).
undefined
10> erlang:register( f1, spawn( exitnormal, f1, [] )).
true
11> whereis(f1) ! kill, ok.
ok
12> whereis(f1).                                      
undefined
13> whereis(f2).           
<0.59.0>
14> c(exitnormal).
{ok,exitnormal}
15> c(exitnormal).
{ok,exitnormal}
16> whereis(f2).
undefined
17> 

【问题讨论】:

    标签: erlang


    【解决方案1】:

    正如 Erlang 参考手册的the Compilation and Code Loading section 中所述,一个模块在运行系统中可以有两个变体:“当前”和“旧”。当您重新加载一个模块时,新版本成为“当前”版本,之前“当前”版本成为“旧”版本,之前“旧”版本被清除。当旧版本被清除时,任何仍在使用它的进程,或者引用旧版本中的 funs 的进程都会被杀死。这就是为什么你的进程在重新加载代码两次后被杀死的原因。

    即使模块在两次加载之间没有改变,也会发生这种情况;加载动作将无条件触发过渡。

    【讨论】:

    • 变体在编译之前不会寻找代码的变化(我猜)。这解释了进程的终止。我说的对吗?
    猜你喜欢
    • 1970-01-01
    • 2014-04-28
    • 2013-06-25
    • 1970-01-01
    • 2013-07-03
    • 2020-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多