From: Norio Suzuki Date: 2015-02-09T19:57:14+09:00 Subject: [ruby-list:50088] Thead内で作成した子プロセスがゾンビになる 1.9.3から2系列にやっと重い腰を上げて移行を始めた鈴木と申します。 移行中にもしかしたらバグかもしれない現象にあったので報告いたします。もう2.2がリリースされているので、仕様の変更によるものでこれが設計通りの動作なのだとは思いますが、一応。 # 現象 Thread内で作成した子プロセスが終了してもSIGCHLDが親プロセスに送られてこない。 子プロセスが終了すると送られてくるSIGCHLDをtrapしてwaitすることで子プロセスがゾンビ化するのを防ぎたいのですが、Thread内で作成すると子プロセスが終了してもSIGCHLDをtrapすることができません。 またProcess.detach()を使ってみたのですが、Thread内だと同様にゾンビになってしまいました。 この現象はRubyのバージョンに依存しています。2.0と2.1ではこの問題が起きますが、1.9.3ではThread内でプロセスを作成しても、SIGCHLDを捕まえられます。 # テスト環境 Ubuntu 14.04.1 ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux] SIGCHLDを捕まえられる。 Ubuntu 14.04.1 ruby 2.0.0p384 (2014-01-12) [x86_64-linux-gnu] Ubuntu 14.10 ruby 2.1.2p95 (2014-05-08) [x86_64-linux-gnu] SIGCHLDを捕まえられない。 # テストプログラム #!/usr/bin/ruby # -*- coding: utf-8 -*- Signal.trap(:CHLD){ begin while status = Process.waitpid2(-1, Process::WNOHANG|Process::WUNTRACED) print "SIGCHLD: pid_#{status.first}: #{status.last.inspect}\n" end rescue Errno::ECHILD print "SIGCHLD: Errno::ECHILD\n" end } def spawn_proc(from) if pid = fork print "spawn proc(#{pid})\n" # Process.detach(pid) # not work else sleep 1 server(from) exit end end def server(from) print "#{$$}: forked in #{from}\n" sleep rand(10) print "#{$$}: exit\n" exit end Thread.start{ 3.times{ spawn_proc("thread") } } 3.times{ spawn_proc("main") } sleep 30 -- 鈴木教郎