From: Tanaka Akira Date: 2005-02-24T09:56:24+09:00 Subject: [ruby-dev:25756] Re: I/O operation differs signal handler In article <20050224091450P.aamine@loveruby.net>, Minero Aoki 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]