📖
[Bug #21456] IO#close が特定のタイミングだとプロセスが終了しないバグ報告
[Bug #21456] IO.close does not work in a rescue IO::TimeoutError block.
-
IO#closeを呼び出すと強制的にプロセスが終了することを期待する - しかし
IO::TimeoutErrorが発生し、そのタイミングで#closeを呼び出してもプロセスは終了せず、待ち処理が発生してしまうというバグ報告
# 10秒の sleep を行うプロセスを作成
execArg = 'echo testwrite; sleep 10'
tofuProcess = IO.popen(execArg, 'r')
# 5秒でタイムアウトするような設定をする
puts 'executed tofu process.'
tofuProcess.timeout = 5
begin
# プロセスを実行
tofuOut = tofuProcess.read
# 5秒経った段階でタイムアウトが発生して IO::TimeoutError が発生する
rescue IO::TimeoutError
puts 'rescue occured'
# IO::TimeoutError が発生したら即 #close を呼び出しプロセスを終了したい
# しかし、これが即時で終了せずにプロセスの待ち処理が発生する
tofuProcess.close
puts 'process closed'
end
- これなんですが実際には
IO#closeではプロセスへシグナルを送ることはしておらずプロセスを終了させる場合は自分でシグナルを送る必要がある - 例えば以下のような対応をすることでやりたいことが実現できるみたいですね
execArg = 'echo testwrite; sleep 10'
# 孫プロセスから呼び出すので pgroup: を設定しておく必要がある
tofuProcess = IO.popen(execArg, 'r', pgroup: true)
puts 'executed tofu process.'
tofuProcess.timeout = 5
begin
tofuOut = tofuProcess.read
rescue IO::TimeoutError
puts 'rescue occured'
# ここで対象のプロセスを終了する新ぐなるを送る
Process.kill "-TERM", tofuProcess.pid
tofuProcess.close
puts 'process closed'
end
Discussion