[ruby-list:50088] Thead内で作成した子プロセスがゾンビになる
From:
Norio Suzuki <nosuzuki@...>
Date:
2015-02-09 10:57:14 UTC
List:
ruby-list #50088
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
--
鈴木教郎