0

I have a script that runs several child processes using the fork:

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

I need the ability to stop the script by pressing Ctrl+C. But pressing time, some processes may be already dead. as it can be verified?

if you do so:

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

I get an error:

undefined method `exited?' for 27520:Fixnum (NoMethodError)
Marsel.V
  • 1,015
  • 1
  • 12
  • 28

1 Answers1

0

The result of Fork is the PID, so rather than fr.exited? you would need to get the process status from the process with a PID of fr. Unfortunately, Ruby does not have a good way to get the process status from a PID. See Get process status by pid in Ruby

You can simply rescue the exception if you try to kill the process and it is has already completed. instead of:

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

it would be:

forks.each do |fr| 
  begin
    Process.kill 9, fr
  rescue Errno::ESRCH
    puts "process #{fr} already exited"
  end
end
Sam Woods
  • 1,820
  • 14
  • 13