[ruby-list:50103] Re: Thead内で作成した子プロセスがゾンビになる
From:
Tomoyuki Chikanaga <nagachika00@...>
Date:
2015-03-19 17:11:54 UTC
List:
ruby-list #50103
近永と申します。 遅い反応ですみません。。。 まず貼られていたテストプログラムを手元で実行してみましたが以下のような結果でした。 おっしゃるような現象は再現できてないようです。 環境: OS: Ubuntu 14.04 Ruby: 2.2.1 $ ruby -v test.rb ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-linux] spawn proc(21) spawn proc(24) spawn proc(27) spawn proc(30) spawn proc(33) spawn proc(36) 24: forked in thread 21: forked in main 27: forked in main 21: exit 30: forked in thread 30: exit 36: forked in thread 33: forked in main SIGCHLD: pid_21: #<Process::Status: pid 21 exit 0> SIGCHLD: pid_30: #<Process::Status: pid 30 exit 0> 24: exit SIGCHLD: pid_24: #<Process::Status: pid 24 exit 0> 36: exit SIGCHLD: pid_36: #<Process::Status: pid 36 exit 0> 27: exit 33: exit SIGCHLD: pid_27: #<Process::Status: pid 27 exit 0> SIGCHLD: pid_33: #<Process::Status: pid 33 exit 0> SIGCHLD: Errno::ECHILD Signal.trap で設定されたシグナルハンドラがどう実行されるかについてですが C のレベルでは、というか OS のシグナルは timer thread がシグナルを受信し、 これをインタプリタが管理しているフラグにセットして ruby のメインスレッドに 通知することで次の割り込み可能なポイントでメインスレッドが実行するようになっています (首藤さんのおっしゃるように timer thread 以外ではシグナルをマスクしています)。 というわけで Signal.trap で登録する Ruby のシグナルハンドラはプロセス全体で 同じで Thread 毎に設定が必要というようなことはありません。 SIGCHLD については一時期 Signal.trap で変更できないようにされて(記録を漁ってみると r32523) しかしそれは取り消されている(r32528)ので設定できるはず、という認識です。 変更できないようにした時の理由として SIGCHLD のシグナルハンドラを設定すると wait(2) がうまく動作しなくなる環境があるということだったようなのですが、 具体的にどういう環境だったのかは忘れてしまいました。 kosaki さんが知っていたはず。 2015年2月11日 22:48 Norio Suzuki <nosuzuki@postcard.st>: > お教えいただきありがとうございます。 > > > どのスレッドがシグナルを受け取るか分からないとしても、頭にProcess.trapを書いておけばどのスレッドにも受け継がれてtrapされると思っていのですが、これが間違いということなのでしょうか? > > Threadのブロック内にtrapブロックを書いても同じだったので、スレッド内ではシグナルを無視しているように思えます。 >