信号发送到哪个系统调用?

tig*_*tig 2 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
Run Code Online (Sandbox Code Playgroud)

QUIT信号刚丢失.它去哪儿了?有默认处理程序的东西只是忽略它?

如何将信号发送到该fork创建的所有进程?是否可以在不搜索所有子进程的情况下执行此操作?

mae*_*ics 7

问题是该system调用创建了另一个在子shell中运行给定命令的子进程,因此实际上在您的示例中运行了三个进程.此外,Ruby Kernel#system命令通过标准C函数系统(3)实现,该函数调用forkexec创建新进程(在大多数系统上)忽略SIGINT和SIGQUIT,并阻止SIGCHLD.

如果你只是打电话sleep(10000)而不是system("sleep 10000")那么事情应该像你期望的那样工作.您还可以在子项中捕获SIGQUIT以优雅地处理它:

child = fork do
  Signal.trap("QUIT") { puts "CHILD: ok, quitting time!"; exit }
  sleep(10000)
end
Run Code Online (Sandbox Code Playgroud)

如果你真的需要使用来自子进程的"系统"调用那么你可能最好使用显式的fork/exec对(而不是system调用中的隐式),这样你就可以执行自己的信号处理了.第三个分叉的孩子.