我运行这个脚本:
t = fork do
Signal.trap "INT" do
puts "child"
exit
end
sleep 10
end
Signal.trap "INT" do
puts "parent"
Process.kill "INT", t
Process.waitpid t
exit
end
Process.waitpid t
当我按 CTRL+C 时,我得到了
$ ruby sigtest.rb
^Cchild
parent
您可以看到“INT”传递给了每个进程,Process.kill "INT", t
尝试杀死已经死亡的进程。有没有办法让用户 INT 信号只传递给 parent ?输出将是:
$ ruby sigtest.rb
^Cparent
child
解决方案
规则:
- When you press ctrl+c, SIGINT is passed to whole process group.
- When you fork new process, signal handlers are not passed to new process
所以如果你想手动控制子进程信号,你必须改变进程的GID。
见
- http://corelib.rubyonrails.org/classes/Process/Sys.html#M001961
- http://ruby.runpaint.org/processes (paragraph "Options Hash")
def system cmd
pid = fork do
exec cmd, {:pgroup => true}
end
Process.wait pid
$?.success?
end
def ` cmd # `make syntax highlight happy
readme, writeme = IO.pipe
pid = fork do
$stdout.reopen writeme
readme.close
exec cmd, {:pgroup => true}
end
writeme.close
data = readme.read
Process.wait pid
data
end
最佳答案
您总是可以让 child 忽略 INT
信号。
关于ruby - Ruby 中的进程间信号处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6927993/