2017-02-10 12 views
0

У меня есть сценарий, который работает несколько дочерних процессов с помощью вилки:рубин получить вилку ПИД-

def my_fork s 
    puts "start fork #{s}, pid #{Process.pid}" 
    sleep s 
    puts "finish" 
end 

forks = [] 
5.times do |t| 
    forks << fork do 
    my_fork t+5 
    end 
end 

begin 
    Process.waitall 
rescue Interrupt => e 
    puts "interrupted!" 
    forks.each{|fr| Process.kill 9, fr} 
end 

мне нужна возможность остановить сценарий, нажав Ctrl + C. Но нажимая время, некоторые процессы могут быть уже мертвы. как это можно проверить?

если вы делаете так:

forks.each{|fr| puts fr.exited?; Process.kill 9, fr} 

Я получаю сообщение об ошибке:

undefined method `exited?' for 27520:Fixnum (NoMethodError) 

ответ

0

Результат Fork является PID, так что вместо fr.exited? вам нужно будет получить статус процесса из процесса с помощью PID fr. К сожалению, у Ruby нет хорошего способа получить статус процесса из PID. См. Get process status by pid in Ruby

Вы можете просто спасти исключение, если попытаетесь убить процесс, и он уже завершен. вместо:

forks.each{|fr| Process.kill 9, fr} 

было бы:

forks.each do |fr| 
    begin 
    Process.kill 9, fr 
    rescue Errno::ESRCH 
    puts "process #{fr} already exited" 
    end 
end