2016-03-27 10 views
1

Modultest:Erlang: spawn_link Prozesse nicht getötet werden, wenn alles heruntergefahren normalerweise

tester() -> 
    receive 
     X -> 
      erlang:display("message.."), 
      tester() 
    end. 


initialize() -> 
    spawn_link(?MODULE, tester, []), 
    erlang:display("Started successfully."). 

REPL:

length(erlang:processes()). -> 23 
Pid = spawn_link(test, initialize, []). 
length(erlang:processes()). -> 24 
exit(Pid). 
length(erlang:processes()). -> 24 

Es scheint, dass der erzeugte Tester Prozess noch läuft! Wie stelle ich sicher, dass alle spawn_link-Prozesse auch beendet werden, wenn ich meine Anwendung beende?

+0

' exit (Pid) 'wird tatsächlich fehlschlagen, weil der Prozess, der 'test: initialize/0' ausführt, fast augenblicklich zurückkehrt. Ist das beabsichtigt? – Dogbert

Antwort

4

Nun, Sie starten eigentlich zwei Erlang Prozesse, nicht einen. Der erste, an den Sie das Signal exit senden, stirbt, bevor Sie das Ausgangssignal senden, also hat die keine Wirkung.

Der erste Prozess, den Sie in dieser Zeile in der Shell starten:

Pid = spawn_link(test, initialize, []). 

Dieser Prozess Ausführung startet die initialize Funktion, in der sie den zweiten Prozess beginnt, und es stirbt dann, weil es nichts anderes zu tun, . Dies ist der Prozess, an den Sie das Signal exit senden möchten.

Um dies zu beheben einfach die richtigen Pid aus der Initialisierungsfunktion zurück:

initialize() -> 
    Pid = spawn_link(?MODULE, tester, []), 
    erlang:display("Started successfully."), 
    Pid. 

Und es direkt starten:

Pid2 = test:initialize(). 

Dann werden Sie in der Lage sein, es zu töten mit exit(Pid2).

+0

Ich verstehe es jetzt, aber immer noch spawn_link ist bidirektional, also wenn initialize Prozess getötet wird, sollte Tester Prozess auch töten. Aber das ist nicht der Fall. Und wie kann ich das tun? –

+0

Der erste Prozess wird nicht beendet, er stirbt, bevor es Ihnen gelingt, das Exit-Signal zu senden, da kein Code mehr ausgeführt werden muss. Und wenn ein Prozess aus diesem Grund stirbt, wird gesagt, dass er normal austritt, so dass die Verbindung zwischen Prozessen nicht den anderen Prozess zum Absturz bringt. Siehe Empfangen von Exit-Signalen in http://erlang.org/doc/reference_manual/processes.html#id86927 Sie könnten 'exit (something) .' am Ende der Initialisierungsfunktion hinzufügen. Auf diese Weise wird der Prozess nicht normal enden und der damit verbundene Prozess wird damit enden. – Amiramix

+0

Ich sehe, danke !! –