2011-11-21 10 views
7

Obecnie robię to w jednym poleceniem niezwłocznegozabić proces i procesy składowe w Ruby w systemie Windows

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

a następnie w innym

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

Problem polega na tym, że proces I tarło (serwer Rails w tym przypadku) spawnuje łańcuch podprocesów. Komenda kill nie zabija ich, po prostu zostawia ich osieroconych bez rodzica.

Jakieś pomysły, w jaki sposób mogę zabić cały zrodzony proces i wszystkie jego dzieci?

Odpowiedz

4

I ostatecznie rozwiązany to w następujący sposób

Najpierw zainstalowałem SYS-proctable gem

gem install 'sys-proctable' 

następnie używany pierwotnie opublikowany kod do spawn proces i dodaje się go zabić (błąd manipulacja pominięte dla zwięzłości)

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 

można zmienić kill 9 do czegoś trochę mniej ofensywa oczywiście, ale to jest sedno rozwiązania.

+0

Zastanawiam się, czy pętla, aby uzyskać procs jest niezawodny. W procesach Linux-a może być nieczynnych, więc może być potrzebnych kilka iteracji, aby złapać wszystkie. – akostadinov

-2

Jedno-skryptowe rozwiązanie bez klejnotów. Uruchom skrypt, CTRL-C, aby zatrzymać wszystko:

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 
+0

Nie widzę, jak to by działało. 'spawn' zwraca pojedynczy pid (nie wszystkie pid dzieci). Dodanie tego pid do tablicy i zapętlenie jest zbędne. – AlexChaffee