[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ブロックを書いても同じだったので、スレッド内ではシグナルを無視しているように思えます。
>

In This Thread