jahyun
unread,Dec 13, 2007, 10:13:30 AM12/13/07Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to erlangstudy
Programming Erlang의 Error In Concurrent Programs에 설명이 좀 잘못 설명된 부분이 있는
것 같은데요..
첫 번째는 exit signal에 대한 설명 중에 아래와 같은 내용이 있는데
(p.163) In addition, a process Pid1 can explicitly send an exit signal
X to a process Pid2 by evaluating exit(Pid2, X). The process that
sends the exit signal does not die; it resumes execution after it has
sent the signal. Pid2 will receive a { 'EXIT', Pid1, X } message (if
it is trapping exits), exactly as if the originating process had died.
Using this mechanism, Pid1 can "fake" it own death (this is
deliberate).
실제로 테스트를 해보면, Pid1이 system process일 때 Pid2가 exit( Pid1, Reason )과 같은 형태
로 호출하더라도 Pid1이 Pid2가 죽었다고 생각하지 않는 것 같습니다. edemo2.erl을 약간 변형해서 테스트를 해봤는데
요..
%
% edemo2.erl 중 수정한 것..
%
start(Bool, M) ->
%% Spawn three process A B and C
A = spawn(fun() -> a() end),
B = spawn(fun() -> b(A, Bool) end),
C = spawn(fun() -> c(B, M) end),
sleep(1000),
status(a, A),
status(b, B),
status(c, C),
{ A, B, C }.
% ...
c(B, M) ->
%process_flag(trap_exit, true),
link(B),
exit(B, M),
wait(c).
wait(Prog) ->
receive
goodbye ->
true;
Any ->
io:format("Process ~p received ~p~n",[Prog, Any]),
wait(Prog)
end.
% ...
위와 같이 수정하고, 다음과 같이 테스트를 했습니다.
16> { A, B, C } = edemo2:start( true, { die, abc } ).
Process b received {'EXIT',<0.77.0>,{die,abc}}
process a (<0.75.0>) is alive
process b (<0.76.0>) is alive
process c (<0.77.0>) is alive
{<0.75.0>,<0.76.0>,<0.77.0>}
c는 exit/2 호출 후에 wait/1를 수행하므로 alive되는 건 맞습니다. 하지만 제가 책의 설명을 이해한 대로라면 B
는 C가 죽은 줄 알아야 합니다. 그런데 B의 process_info를 보면
17> process_info( B ).
[{current_function,{edemo2,wait,1}},
{initial_call,{erlang,apply,2}},
{status,waiting},
{message_queue_len,0},
{messages,[]},
{links,[<0.75.0>,<0.77.0>]},
{dictionary,[]},
{trap_exit,true},
{error_handler,error_handler},
{priority,normal},
{group_leader,<0.23.0>},
{total_heap_size,233},
{heap_size,233},
{stack_size,2},
{reductions,22},
{garbage_collection,[{fullsweep_after,65535}]},
{suspending,[]}]
B에 대한 link set으로 여전히 C가 존재합니다. 그리고
18> C ! goodbye.
Process b received {'EXIT',<0.77.0>,normal}
goodbye
이렇게 해서 실제 C가 종료가 되어야, B의 link set에서 C가 없어집니다. 이런 상황이라면 C가 죽은 척 할 수 없는 것
이 아닌가요?
B가 normal process일 때는 상황이 더 심각(?)해지는데 C가 exit( B, Reason) (reason is
not normal)을 호출하면 B는 exit signal을 trap할 수 없기 때문에 그냥 죽습니다. 이 때, B가 죽으면서
자신의 link set에 자기가 죽었다고 exit signal을 보냅니다. 그럼 역시 C도 그 signal을 받게 되고 같이 죽
습니다..-_-;; 이렇게 해도 저렇게 해도 죽은 척은 못하는 상황인거죠..
두 번째는 ... untrappable exit signal에 관한 겁니다.
(p.163) If the reason is given as kill, then an untrappable exit
signal will be sent. An untrappable exit signal will always kill the
process it is sent to, even if it is a system process.
라고 설명이 되어 있는데 kill을 exit/1으로 호출하면 호출자와 link된 system process는 해당 exit
signal을 trap해 버립니다. exit/2로 호출하는 경우에만 exit reason이 kill인 exit signal을
trap하지 못하더군요. 이 부분은 책의 p.169의 edemo1의 결과와 edemo2의 결과만 비교해 봐도 바로 알 수 있
죠. 그런데 이 결과에 대한 자세한 설명은 없더라구요. edemo2의 결과에 대한 것은 아예 설명이 없고요.
8> edemo1:start(true, {die,kill}).
Process b received {'EXIT',<0.73.0>,kill}
process b (<0.72.0>) is alive
process c (<0.73.0>) is dead
ok
6> edemo2:start(true, kill).
Process c received {'EXIT',<0.109.0>,killed}
Process a received {'EXIT',<0.109.0>,killed}
process b (<0.109.0>) is dead
process c (<0.110.0>) is alive
ok
만약에 Trapping Exit Signal (Advanced)에 대한 내용을 자세히 살펴보지 않고 책에 있는 내용만 곧이곧대
로 믿었다면 잘못 이해한 상태에서 프로그래밍 하게 되지 않을까 싶은데요..
마음 같아서는 위와 같은 설명이 잘못된 것이 아니냐고 저자에게 직접 물어보고 싶은데.. 영작의 압박과 혹시 제가 잘못 이해한 부
분이 있는 것은 아닌지, 그리고 혹시 이전 스터디에서 위와 같은 내용이 이미 논의된 적이 있는지 궁금해서요.. @@
다른 분들 생각은 어떠신가요??
/jahyun