问题
If I created processes with Process.new, they can be killed with .kill. However, they become zombies in a Signal trap:
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
Running this code with crystal run and sending a SIGINT to the process, will always have .terminated? return true for the process because it is in a zombie (<defunct>) state.
回答1:
Processes become zombies when their parent does not collect their status, that is when it doesn't call any of the wait family of functions.
For your example you should keep the Process instance around and call Process#wait after sending the kill signal. If you want to do this concurrently for many process just surround each call to wait with a spawn.
来源:https://stackoverflow.com/questions/50811354/why-do-processes-killed-in-a-signal-trap-block-become-zombies-instead-of-termina