2013-03-07 11 views
5

Ho uno script di seguito utilizzando Thor per l'esecuzione come un'attività rake che gestisce ARGV.Come uccidere tutti i processi all'interno del rubino Thor in stop?

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

Quando inizia ruby script.rb start, genera due sottoprocessi (totale tre). La mia domanda è come uccidere tutti i processi quando eseguo ruby script.rb stop. Ho visto in giro per il web che, all'inizio, dovrei memorizzare il processo genitore pid in un file e, una volta fermato, l'ho letto e ucciso. Il problema è che uccidere il genitore non uccide i bambini. Quindi potrei salvare tutti e tre i pid nel file e ucciderli uno dopo l'altro.

Mi chiedo quale sia il modo giusto per farlo e se il modo in cui sto lavorando con i processi all'interno dello start sia corretto.

+2

Conservazione del PID sul file system sembra essere una pratica abbastanza comune di servizi daemonized, nel tuo caso lo fa sembra che memorizzare tutti i PID sul file system abbia senso, è il modo più sicuro per uccidere i processi corretti. –

+0

grazie per la tua risposta! – Luccas

+0

Una possibile alternativa sarebbe quella di collegare un finalizzatore quando l'oggetto ottiene GC'd che si ripulire correttamente dopo se stesso. http://stackoverflow.com/questions/5956067/ruby-destructors Puoi anche utilizzare Daemons gem per gestire i processi. http://daemons.rubyforge.org/ –

risposta

0

Se si conosce il PID genitore si possono trovare e uccidere tutti i bambini come questo:

# 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) } 
Problemi correlati