我正在通过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/