2014-09-04 43 views
0

在Erlang中,我創建了兩個彼此鏈接的進程。如果我退出表單一個過程,則另一個忽略它,如果正常退出。這種行爲可以在a link中看到。Erlang進程:被鏈接進程忽略的正常退出,在「編譯兩次」之後退出

我的問題是,編譯相同的代碼兩次,我可以看到第二個進程也退出。下面是我的示例代碼:

-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> 

回答

1

如二郎神參考手冊the Compilation and Code Loading section描述,模塊可以在運行系統中兩個變種: 「當前」和「老」。當您重新加載模塊時,新版本將成爲「當前」版本,之前「當前」的版本將變爲「舊版本」,而之前「舊版本」的版本將被清除。當舊版本被清除時,任何仍然使用它的進程或者引用舊版本的進程都會被終止。這就是爲什麼你的進程在重新加載代碼兩次後被終止的原因。

即使模塊在兩次加載之間沒有改變,也會發生這種情況;裝載行爲將無條件觸發過渡。

+0

在編譯之前,這些變體不會查找代碼中的更改(我猜)。這就解釋了流程的終止。我對麼。 – 2014-09-04 12:11:39

+0

是的,沒錯。 – legoscia 2014-09-04 12:35:04