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进程发送信号。我认为问题在于系统命令。系统命令创

给出一个非常简单的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进程发送信号。我认为问题在于系统命令。系统命令创建新的fork并等待它结束,我认为这种等待阻止了您的退出信号。如果将示例作为test.rb运行,您将看到三个过程:

  • test.rb
  • test.rb
  • 睡10000

如果您发送信号“TERM”或“KILL”而不是“QUIT”,则第二个test.rb将消失,但sleep 10000将继续

问题在于,
system
调用会在子shell中创建另一个子进程来运行给定的命令,因此在您的示例中实际上有三个进程在运行。此外,Ruby
Kernel#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子进程中执行自己的信号处理