过程如何以Process.wait不会注意到的方式死亡?

Joh*_*hir 12 ruby signals process

我有这个ruby脚本来管理que进程.que不支持多进程,请参见此处的讨论):

#!/usr/bin/env ruby

cluster_size = 2    
puts "starting Que cluster with #{cluster_size} workers"; STDOUT.flush

%w[INT TERM].each do |signal|
  trap(signal) do
    @pids.each{|pid| Process.kill(signal, pid) }
  end
end

@pids = []
cluster_size.to_i.times do |n|
  puts "Starting Que daemon #{n}"; STDOUT.flush
  @pids << Process.spawn("que --worker-count $MAX_THREADS")
end

Process.waitall

puts "Que cluster has shut down"; STDOUT.flush
Run Code Online (Sandbox Code Playgroud)

该脚本已经运行了几个月.有一天,我发现脚本正在运行的状态,但两个子进程都已经死了.

我试图复制这个实验.我用各种信号杀死了孩子,让他们提出异常.在所有情况下,脚本都知道该过程已经死亡并且本身已经死亡.

如果没有父母的脚本知道,孩子的过程怎么会死?

tuk*_*kan 3

子进程怎么可能在父脚本不知情的情况下死亡呢?

我的猜测是子进程变成了僵尸并且错过了Process.waitall。发生这种情况时您是否检查过子进程是否为僵尸进程?

僵尸进程:如果您有僵尸进程,则意味着这些僵尸进程尚未被其父进程等待(检查 with PPIDps -l。最后你有三个选择: 修复父进程(让它等待);杀死父母;或者克服它。

你能检查一下你的信号列表trap吗?

您可以列出所有可用的信号(下面是在 Windows 上):

Signal.list
=> {"EXIT"=>0, "INT"=>2, "ILL"=>4, "ABRT"=>22, "FPE"=>8, "KILL"=>9, "SEGV"=>11, "TERM"=>15}
Run Code Online (Sandbox Code Playgroud)

您可以尝试trap通过例如INT(注意:每个信号可以有一个陷阱)(

Signal.trap('SEGV') { throw :sigsegv }

catch :sigsegv
    start_what_you_need
end
puts 'OMG! Got a SEGV!'
Run Code Online (Sandbox Code Playgroud)

由于你的问题很笼统,所以很难给你一个具体的答案。