In article <20050224091450P.aamine / loveruby.net>,
  Minero Aoki <aamine / loveruby.net> writes:

> 以下のようなプログラムを実行して SIGTERM を送っても、
> $stdin.gets が戻るまでシグナルハンドラが実行されません。
>
>   Signal.trap(:TERM) { puts 'TERM'; exit }
>   puts $$
>   while true
>     p $stdin.gets()
>   end
>
> pure Ruby 版の FastCGI サーバでこのようなコードが必要になりました。
> FastCGI サーバは常に stdin を待ち受けますが、SIGUSR1 でリジューム、
> SIGTERM で exit 0 をするという規約があるので、I/O 待ちをしつつ
> リアルタイムでシグナルも受け付ける必要があります。
>
> これが動作しないと事実上シグナルが効かなくなるので、例えば Apache
> が停止しても ruby プロセスだけが残ってしまうという問題があります。
> うちのサーバでは毎日ログをローテートするたびに ruby プロセスが死に
> 損なっていました。
>
> なお、上記のコードが動作しない原因は [ruby-dev:25003] で導入された
> signal.c:1.55 がそのままになっていることだと思います。そのあとの
> 展開でこのリビジョンの変更は不要になっているはずなので、巻き戻す
> べきではないでしょうか。

その方向の変更は、データが蒸発・重複する原因を除去困難にするため、あま
り賛成できません。

その問題は次のどちらかで解決できないでしょうか。

* Thread.new { sleep } とかをいれて、マルチスレッドにする
  read の前の select でブロックが起これば、signal handler は即座に起動
  するかも知れない

* nonblocking にする
  read の後の select でブロックが起これば、signal handler は即座に起動
  するかも知れない
-- 
[田中 哲][たなか あきら][Tanaka Akira]