忽略发送到我自己的进程组的信号

时间:2015-11-04 10:47:39

标签: ruby unix signals

我正在为一组子进程编写一个包装器,我想对一些信号进行响应并将它们传播给子进程。因此,例如,如果包装器收到QUIT,它应该向所有子项发送QUIT(不仅是直接子项,而且还会生成所有进程)。

所以我使用setsid,然后使用刚刚发出kill(sig, 0)的代码捕获我想要处理的信号。当我这样做时,包装器也会再次获得信号(作为会话领导者和进程组内部)并且随后会出现无限循环。

我正在考虑设置某种标志(already_handled_sig_X)并在调用kill之前咨询它,但是(a)它看起来很笨拙而且(b)我何时删除该标志?

BTW:实现语言是Ruby,所以如果你想放置例子并且想用Ruby编写它们我会欣赏它,否则 - 不要打扰,我可以处理C。

这是我目前的(幼稚)实施:

def run_stuff(cmd)
  fork do
    Process.setsid
    trap(:QUIT) { Process.kill(:QUIT, 0) }
    trap(:TERM) { Process.kill(:TERM, 0) }
    IO.popen(cmd) do |io|
      while line = io.gets
        $log.warn line
      end
    end
  end
end

1 个答案:

答案 0 :(得分:1)

最后,我只是设置一个标志来忽略其他信号。因此应修改上面的示例代码:

def run_stuff(cmd)
  fork do
    Process.setsid
    shuttingdown = false
    trap(:QUIT) do
      next if shuttingdown
      shuttingdown = true
      Process.kill(:QUIT, 0)
    end
    trap(:TERM) do
      next if shuttingdown
      shuttingdown = true
      Process.kill(:TERM, 0)
    end
    IO.popen(cmd) do |io|
      while line = io.gets
        $log.warn line
      end
    end
  end
end