【发布时间】:2011-10-19 04:06:12
【问题描述】:
我运行这个脚本:
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 信号只传递给父级?输出将是:
$ ruby sigtest.rb
^Cparent
child
解决方案
规则:
- 当您按下 ctrl+c 时,SIGINT 将传递给整个进程组。
- 当您派生新进程时,信号处理程序不会传递给新进程
所以如果你想手动控制子进程信号,你必须改变进程的 GID。
见
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
【问题讨论】:
标签: ruby ipc signals system-calls