代码之家  ›  专栏  ›  技术社区  ›  John Bachir

一个进程怎么会以这样的方式死去。等等,你不会注意到吗?

  •  12
  • John Bachir  · 技术社区  · 8 年前

    que 过程。que不支持多进程,请参阅讨论 here

    #!/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
    

    这个剧本已经好几个月了。前几天,我发现脚本运行的状态,但是两个子进程都死了。

    我试着复制这个。我用各种信号杀死孩子,让他们提出例外。在所有情况下,剧本都知道这个过程结束了,而自己也死了。

    2 回复  |  直到 8 年前
        1
  •  3
  •   tukan    8 年前

    如果没有父脚本,子进程怎么会终止 知道?

    我猜孩子的进程变成了僵尸 Process.waitall

    僵尸: 如果您有僵尸进程,这意味着这些僵尸没有被它们的父进程等待(检查 PPID 具有 ps -l

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

    Signal.list
    => {"EXIT"=>0, "INT"=>2, "ILL"=>4, "ABRT"=>22, "FPE"=>8, "KILL"=>9, "SEGV"=>11, "TERM"=>15}
    

    你能试着 陷阱 通过例如。 INT (注意:每个信号可以有一个陷阱)(

    Signal.trap('SEGV') { throw :sigsegv }
    
    catch :sigsegv
        start_what_you_need
    end
    puts 'OMG! Got a SEGV!'
    

    因为你的问题是一般性的,所以很难给你一个具体的答案。

        2
  •  2
  •   Craig.Feied    7 年前

    僵尸并不是造成这个问题的唯一可能原因——停止的孩子可能不会因为各种原因被报告。

    与僵尸不同的是,僵尸无法完全收割,因为它们没有可访问的父代, 冻结过程

    在某些平台上,Ruby可以使用以下语法添加一个标志,请求返回尚未报告的已停止子级:

    waitpid(pid, Process::WUNTRACED)
    

    waitall 没有接受标志的版本,因此您必须自己将其聚合,或使用 pid = -1 等待任何子进程(如果省略了pid,则为默认值)或 pid = 0 等待与调用进程具有相同进程groupID的任何子进程。

    here .