Ruby 中的进程间信号处理
我运行这个脚本:
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
You can see that "INT" was pass to every process and Process.kill "INT", t
try to Kill 已经死亡的进程。有没有办法让用户 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
I run this script:
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
When I do CTRL+C, I get
$ ruby sigtest.rb
^Cchild
parent
You can see that "INT" passed to every process and Process.kill "INT", t
try to kill process which already died. Is there way to do so that user INT signal will be passed only to the parent? And output will be:
$ ruby sigtest.rb
^Cparent
child
Solution
Rules:
- 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
So if you want to control child process signals manually, you have to change GID of the process.
See
- 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您始终可以让孩子忽略
INT
信号。You could always have the child ignore the
INT
signal.