【问题标题】:Kill process and sub-processes in Ruby on Windows在 Windows 上杀死 Ruby 中的进程和子进程
【发布时间】:2023-12-31 07:55:02
【问题描述】:

目前我在一个命令提示符下执行此操作

require 'win32/process'
p = Process.spawn("C:/ruby193/bin/bundle exec rails s")
puts p
Process.waitpid(p)

然后在另一个

require 'win32/process'
Process.kill(1,<p>)

问题是我生成的进程(在本例中为 Rails 服务器)生成了一系列子进程。 kill 命令不会杀死它们,只会让它们成为没有父级的孤儿。

有什么办法可以杀死整个生成的进程及其所有子进程

【问题讨论】:

    标签: ruby windows win32-process


    【解决方案1】:

    我最终通过以下方式解决了这个问题

    首先我安装了 sys-proctable gem

    gem install 'sys-proctable'
    

    然后用原来贴的代码spawn这个进程,然后用下面的代码杀死它(为了简洁省略了错误处理)

    require 'win32/process'
    require 'sys/proctable'
    include Win32
    include Sys
    
      to_kill = .. // PID of spawned process
      ProcTable.ps do |proc|
        to_kill << proc.pid if to_kill.include?(proc.ppid)
      end
    
      Process.kill(9, *to_kill)
      to_kill.each do |pid|
        Process.waitpid(pid) rescue nil
      end
    

    当然,您可以将 kill 9 更改为稍微冒犯性的东西,但这是解决方案的要点。

    【讨论】:

    • 我想知道获取 procs 的循环是否可靠。在 Linux 上,进程可能出现故障,因此可能需要进行几次迭代才能捕获所有进程。
    【解决方案2】:

    没有任何宝石的单一脚本解决方案。运行脚本,CTRL-C 停止一切:

    processes = []
    processes << Process.spawn("<your process>")
    
    loop do
      trap("INT") do
        processes.each do |p|
          Process.kill("KILL", p) rescue nil
          Process.wait(p) rescue nil
        end
        exit 0
      end
      sleep(1)
    end
    

    【讨论】:

    • 我不明白这将如何工作。 spawn 返回单个 pid(不是所有子 pid)。您将该 pid 添加到数组并循环的事实是多余的。
    最近更新 更多