How to check if child process is still alive?


#1

how do you check if your child process from fork still alive or not? In
perl
I can send kill(0, $cid), I think. But Process.kill(0, child_id) always
returns 1.

To be honest, I couldn’t get the perl code to work either. It always
returns
1 too.

I can do ps -p #{child_id} but I wonder if Process.kill should work
too.

-andre


#2

On Thu, 1 Mar 2007, Andreas S wrote:


Win a Zune™—make MSN® your homepage for your chance to win!
http://homepage.msn.com/zune?icid=hmetagline

 #
 # returns true if pid is running, false otherwise
 #
   def alive pid

#–{{{
pid = Integer("#{ pid }")
begin
Process::kill 0, pid
true
rescue Errno::ESRCH
false
end
#–}}}
end
alias alive? alive

it should always return 1. it raises if the pid is dead or you do not
have
permission to signal the process.

-a


#3

On Feb 28, 2007, at 5:17 PM, Andreas S wrote:

how do you check if your child process from fork still alive or
not? In perl I can send kill(0, $cid), I think. But Process.kill(0,
child_id) always returns 1.

To be honest, I couldn’t get the perl code to work either. It
always returns 1 too.

I can do ps -p #{child_id} but I wonder if Process.kill should
work too.

Using Process.kill(0, pid) will return 1 as long as the process
exists. In
your situation, I’m guessing that the child process has terminated
but continues to exist as a zombie process. You have to call
Process.wait
to reap the child process in order for the child process to disappear
entirely.

pid = fork { sleep(10) }

puts Process.kill(0, pid) # 1
sleep 15
puts Process.kill(0, pid) # 1, process is a zombie at this point
Process.wait
puts Process.kill(0, pid) # exception, process doesn’t exist

Gary W.


#4

You have to call Process.wait to reap the child process in order for the
child process to disappear entirely.

Gary W.

I don’t want to use Process.wait because it will block. I have a queue
that
I want to refill with the next job in line when a slot is available. I’m
not
gaining much from forking jobs like this but my main purpose is to
emulate
LSF queue on local machine, in case its down or something. By doing so,
the
rest of the code still sees a queue.

I tried Ara’s suggestion, but it doesn’t seem to throw exception.

Thanks for such prompt response and I love how Ara, even for merely
showing
example, gave
alias alive? alive
:slight_smile:

-andre

def alive pid
pid = Integer("#{ pid }")
begin
Process::kill 0, pid
true
rescue Errno::ESRCH
false
end
end

c = fork do
sleep 5
print “Child exits”
exit
end

while alive c
print ‘.’; STDOUT.flush
sleep 1
end

ruby test.rb
…Child exits…


#5

Andreas S wrote:

You have to call Process.wait to reap the child process in order for
the child process to disappear entirely.

I don’t want to use Process.wait because it will block.

Then you should use Process.detach(child_pid)

Daniel


#6

Then you should use Process.detach(child_pid)

Daniel

Hey, that does the trick. Thanks a lot Daniel, and to Gary and Ara.

-andre