Ruby 发送到哪个进程的信号称为系统?
给出一个非常简单的ruby脚本:Ruby 发送到哪个进程的信号称为系统?,ruby,signal-processing,Ruby,Signal Processing,给出一个非常简单的ruby脚本: child = fork do system 'sleep 10000' end 5.times do sleep 1 puts "send kill to #{child}" Process.kill("QUIT", child) end 退出信号刚刚丢失。它去哪里了?某个默认处理程序忽略了它 如何向该fork创建的所有进程发送信号?不搜索所有子进程就可以这样做吗?我认为您正在正确地向fork进程发送信号。我认为问题在于系统命令。系统命令创
child = fork do
system 'sleep 10000'
end
5.times do
sleep 1
puts "send kill to #{child}"
Process.kill("QUIT", child)
end
退出信号刚刚丢失。它去哪里了?某个默认处理程序忽略了它
如何向该fork创建的所有进程发送信号?不搜索所有子进程就可以这样做吗?我认为您正在正确地向fork进程发送信号。我认为问题在于系统命令。系统命令创建新的fork并等待它结束,我认为这种等待阻止了您的退出信号。如果将示例作为test.rb运行,您将看到三个过程:
- test.rb
- test.rb
- 睡10000
如果您发送信号“TERM”或“KILL”而不是“QUIT”,则第二个test.rb将消失,但sleep 10000将继续 问题在于,
system
调用会在子shell中创建另一个子进程来运行给定的命令,因此在您的示例中实际上有三个进程在运行。此外,RubyKernel#system
命令是通过标准C函数实现的,该函数调用fork
和exec
来创建新进程,并且(在大多数系统上)忽略SIGINT和SIGQUIT,并阻止SIGCHLD
如果您只是调用sleep(10000)
而不是system(“sleep 10000”)
,那么事情应该按照您的预期进行。您还可以在子对象中设置SIGQUIT以优雅地处理它:
child = fork do
Signal.trap("QUIT") { puts "CHILD: ok, quitting time!"; exit }
sleep(10000)
end
如果您确实需要使用来自子进程的“系统”调用,那么最好使用显式fork/exec对(而不是system
调用中的隐式fork/exec对),这样您就可以在第三个fork子进程中执行自己的信号处理