2013-03-07 82 views
5

我有一个脚本,下面使用Thor像管理ARGV的耙子任务那样运行。如何杀死ruby Thor中的所有进程停止?

#!/usr/bin/env ruby 
require "thor" 

class Run < Thor 

    desc "start", "start script" 
    def start 
     p1 = fork{ loop... } 
     p2 = fork{ loop... } 

     # 3 processes running 

     Process.detach(p1) 
     Process.waitpid(p1) 

    end 

    desc "stop", "stop script"  
    def stop 
    # kill all 3 pids 
    end 

end 

Run.start 

当开始ruby script.rb start时,它产生两个子过程(总共三个)。我的问题是当我执行ruby script.rb stop时如何杀死所有进程。我在网上看到,在开始时,我应该将pid父进程存储到一个文件中,当停止时,我读取并杀死它。问题是杀死父母并不会杀死孩子。所以我可以将所有三个pid保存在文件中,然后一个一个地杀掉。

我在问自己什么是正确的方式来做到这一点,以及我在start中处理流程的方式是否正确。

+2

文件系统上存储的PID似乎是进程化服务一个相当普遍的做法,在你的情况下,它确实听起来像将所有PID存储在文件系统上是合理的,这是杀死正确流程的最可靠方法。 – 2013-04-23 14:43:36

+0

感谢您的回答! – Luccas 2013-04-23 15:47:31

+0

另一种可能的选择是在对象获取GC'd后自动附加清理器。 http://stackoverflow.com/questions/5956067/ruby-destructors你也可以使用守护进程gem来管理进程。 http://daemons.rubyforge.org/ – 2013-05-12 01:14:23

回答

0

如果你知道你的父母的PID,你可以找到并杀死所有的孩子是这样的:

# Find child pids, works on Linux/OSX 
def child_pids(pid) 
    pipe = IO.popen("ps -ef | grep #{pid}") 
    pipe.readlines.map do |line| 
    parts = line.strip.split(/\s+/) 
    parts[1].to_i if parts[2] == pid.to_s and parts[1] != pipe.pid.to_s 
    end.compact 
end 

# kill -9 every child 
child_pids(parent_pid).each { |pid| Process.kill('TERM', pid) }