我正在通过ruby学习系统编程,但无法理解这种行为:

pid = fork do
  Signal.trap("USR1") do
    puts "hello!"
  end
  Signal.trap("TERM") do
    puts "Terminating"
    exit
  end
  loop do
  end
end

Process.detach(pid)

Process.kill("USR1", pid)
Process.kill("USR1", pid)
Process.kill("USR1", pid)
Process.kill("USR1", pid)

Process.kill("TERM", pid)

正如我所期望的那样输出:
hello!
hello!
hello!
hello!
Terminating

但是,如果我注释掉Process.detach,则子进程似乎只响应一次信号(终止后才响应?):
Terminating
hello!

我困惑为什么在不分离流程的情况下会发生这种情况,即使我四次发送USR1也是如此。有人可以帮忙解释这种行为吗?我认为我不了解分离流程意味着什么。

非常感谢!

最佳答案

我怀疑这全都取决于时间安排-也就是说,差异是由于您的主流程和 fork 流程的指令计划如何相对于彼此运行。

当您执行Process.detach时,将创建一个新线程,该线程等待给定进程的退出结果。您可以将Process.detach替换为

Thread.new { Process.wait(pid) }

并获得相同的效果。我怀疑调用detach(并产生一个新线程)会给您 fork 的过程带来副作用,即可能会产生调度的机会。

如果您没有分离,那么我想您告诉分支的过程死时,您的 fork 过程将没有机会运行。

您可以通过在代码中插入一些sleep调用来了解相对定时的含义,以了解是否可以在不分离的情况下获得相同的观察到的行为。

例如,这似乎对我有用,尽管您的里程可能因主机平台而异:
pid = fork do
  Signal.trap("USR1") do
    puts "hello!"
  end
  Signal.trap("TERM") do
    puts "Terminating"
    exit
  end
  loop do
  end
end

sleep(1)

Process.kill("USR1", pid)
Process.kill("USR1", pid)
Process.kill("USR1", pid)
Process.kill("USR1", pid)

sleep(1)

Process.kill("TERM", pid)

这将产生:
hello!
hello!
hello!
hello!
Terminating

关于ruby - 需要帮助了解 ruby 的Process.detach,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10201115/

10-13 02:20