2013-03-07 1 views
5

Thorを使用してARGVを管理するレーキタスクのように実行するスクリプトがあります。ルビーの中のすべてのプロセスを殺すにはどうすればいいですか?

#!/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を起動すると、2つのサブプロセス(計3)を生成します。私の質問は、ruby script.rb stopを実行するとすべてのプロセスを強制終了する方法です。私はWeb上で、pidの親プロセスをファイルに保存し、停止したらそれを読んで殺すべきであることを見てきました。問題は、親を殺しても子供を殺さないということです。だから私はファイルに3つのPIDをすべて保存し、後で1つずつ削除することができます。

これを行う正しい方法と、start内のプロセスを使用して作業している方法が正しいかどうかを確認しています。

+2

はデーモン化サービスのかなり一般的な方法のようです、あなたのケースではそれはありませんファイルシステムにすべてのPIDを格納するようなサウンドは意味がありますが、これは正しいプロセスを強制終了する最も確実な方法です。 –

+0

あなたの答えをありがとう! – Luccas

+0

可能な代替手段は、オブジェクトがGC後に適切にクリーンアップするときにファイナライザを付けることです。 http://stackoverflow.com/questions/5956067/ruby-destructorsデーモンの宝石を使ってプロセスを管理することもできます。 http://daemons.rubyforge.org/ –

答えて

0

あなたの親のpidを知っている場合は、このようなすべての子どもを見つけ、殺すことができます:ファイルシステムに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) } 
関連する問題