为什么在Signal陷阱块中杀死的进程会变成僵尸而不是经常终止?

时间:2018-06-12 07:18:41

标签: crystal-lang

如果我使用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?,因为它处于僵尸(<defunct>)状态。

1 个答案:

答案 0 :(得分:3)

当父母没有收集他们的状态时,即当他们没有调用任何wait系列函数时,进程就会变成僵尸。

对于您的示例,您应该保留Process实例并在发送kill信号后调用Process#wait。如果您想同时为多个流程执行此操作,请使用wait围绕spawn的每次调用。