为什么在信号陷阱块中被杀死的进程会变成僵尸而不是定期终止?



如果我用Process.new创建了进程,可以用.kill杀死它们。然而,他们变成了信号陷阱中的僵尸:

PROCESSES = {} of Int32 => Process
spawn {
loop { sleep 1 }
}
spawn {
x = Process.new("sleep", "100".split)
x.kill
sleep 0.4
puts x.terminated?
x = Process.new("sleep", "100".split)
PROCESSES[x.pid] = x
}

Signal::INT.trap {
Signal::INT.reset
PROCESSES.each { |pid, x|
puts "killing: #{pid}"
x.kill
sleep 1
puts "killed #{pid}? #{x.terminated?}"
}
}
sleep

使用crystal run运行此代码并向进程发送 SIGINT,将始终.terminated?进程返回 true,因为它处于僵尸 (<defunct>( 状态。

当进程的父进程不收集其状态时,即当它不调用任何wait函数系列时,进程就会变成僵尸。

对于您的示例,您应该保留Process实例,并在发送终止信号后调用Process#wait。如果您想同时对许多进程执行此操作,只需用spawn将每个调用wait包围即可。

相关内容

  • 没有找到相关文章

最新更新