我已經寫以下代碼:在Erlang進程環初始過程不會退出
-module(ring).
-export([start/3]).
start(1, 1, Message) -> %special case, no new processes to be launched
io:format(" Start/3, branch 1~n~n"),
loop(self(), 1, 1),
self() ! Message,
self() ! {self(), quit};
start(1, MsgNum, Message) when MsgNum > 1 -> %first process, register self, launch next, send message, loop
io:format(" Start/3 branch 2, ProcNum: ~b, MsgNum: ~b, process: ~p~n~n", [1, MsgNum, self()]),
register(process_1, self()),
self() ! {self(), Message},
NextPid = spawn(ring, start, [2, MsgNum, Message]),
NextPid ! {self(), Message},
loop(NextPid, 1, MsgNum);
start(MsgNum, MsgNum, _) when MsgNum >= 1 -> %last process, don't start new process, quit master, run loop
io:format(" Start/3 branch 3, MsgNum = ProcNum = ~b, process: ~p~n~n", [MsgNum, self()]),
process_1 ! {self(), quit},
loop(process_1, MsgNum, MsgNum);
start(ProcNum, MsgNum, Message) when ProcNum >= 1 -> %everything else, start next process, send it a message, start loop
io:format(" Start/3 branch 4, ProcNum: ~b, MsgNum: ~b, process: ~p~n~n", [ProcNum, MsgNum, self()]),
NextPid = spawn(ring, start, [ProcNum + 1, MsgNum, Message]),
NextPid ! {self(), Message},
loop(NextPid, ProcNum, MsgNum).
loop(NextPid, ProcNum, MsgNum) ->
receive
{Sender, quit} -> % send quit to next process in queue, then terminate with 'ok'
io:format(" Sender: ~p Quitting process ~p Next: ~p~n~n", [Sender, self(), NextPid]),
NextPid ! {self(), quit},
ok;
{Sender, Msg} -> % print message and wait for next message
io:format(" Message: ~w~n procNum: ~b msgNum: ~b sender: ~p self: ~p next: ~p~n~n", [Msg, ProcNum, MsgNum, Sender, self(), NextPid]),
loop(NextPid, ProcNum, MsgNum);
_ -> %flush garbage, should never get here...
io:format(" Oops. Received someting unexpected")
end.
我期望此代碼以啓動一系列的處理,應該每個打印一個消息,然後禮貌退出。例如,如果我運行ring:start(1,3,hola),我希望看到三個進程,三個消息和三個退出。它幾乎工作,除了初始進程不會終止,因爲在這個shell會話看出:
Eshell V5.10.1 (abort with ^G)
1> c(ring).
{ok,ring}
2> processes().
[<0.0.0>,<0.3.0>,<0.6.0>,<0.7.0>,<0.9.0>,<0.10.0>,<0.11.0>,
<0.12.0>,<0.13.0>,<0.14.0>,<0.15.0>,<0.16.0>,<0.17.0>,
<0.18.0>,<0.19.0>,<0.20.0>,<0.21.0>,<0.22.0>,<0.23.0>,
<0.24.0>,<0.25.0>,<0.26.0>,<0.27.0>,<0.28.0>,<0.32.0>]
3> ring:start(1,3,hola).
Start/3 branch 2, ProcNum: 1, MsgNum: 3, process: <0.32.0>
Message: hola
procNum: 1 msgNum: 3 sender: <0.32.0> self: <0.32.0> next: <0.41.0>
Start/3 branch 4, ProcNum: 2, MsgNum: 3, process: <0.41.0>
Message: hola
procNum: 2 msgNum: 3 sender: <0.32.0> self: <0.41.0> next: <0.42.0>
Start/3 branch 3, MsgNum = ProcNum = 3, process: <0.42.0>
Message: hola
procNum: 3 msgNum: 3 sender: <0.41.0> self: <0.42.0> next: process_1
Sender: <0.42.0> Quitting process <0.32.0> Next: <0.41.0>
Sender: <0.32.0> Quitting process <0.41.0> Next: <0.42.0>
Sender: <0.41.0> Quitting process <0.42.0> Next: process_1
ok
4> processes().
[<0.0.0>,<0.3.0>,<0.6.0>,<0.7.0>,<0.9.0>,<0.10.0>,<0.11.0>,
<0.12.0>,<0.13.0>,<0.14.0>,<0.15.0>,<0.16.0>,<0.17.0>,
<0.18.0>,<0.19.0>,<0.20.0>,<0.21.0>,<0.22.0>,<0.23.0>,
<0.24.0>,<0.25.0>,<0.26.0>,<0.27.0>,<0.28.0>,<0.32.0>]
我的長碼道歉/日誌塊,但我認爲這使得它很清楚,啓動/ 3導致啓動三個進程(< 0.32.0>,< 0.41.0>和< 0.42.0>),並且每個進程打印一條消息,並且每個進程都會收到其退出消息。但是,全部完成後,初始進程(< 0.32.0>)仍在運行。我的理解是,一旦沒有更多的代碼可以運行,流程應該終止 - 第一個流程有什麼特別的地方可以阻止它的終止?
在此先感謝。
當然:-)感謝您的清晰和簡潔的解釋。 – Ampers4nd 2013-04-30 15:27:28