Curious interaction between trap and sleep

E

Eric Jacoboni

Hi,

Can someone explain why this code:

-----------------------------------------
fork do
puts("Child's PID: #{Process.pid}")
end

trap:)SIGCHLD) do
$pid = Process.wait
end

puts("Parent's PID: #{Process.pid}")
puts("My son is no more a zombie (check with ps)...")

sleep(20)

if $?.exitstatus == 0
puts("#{$pid} died gracefully")
else
puts("#{$pid} doesn't die gracefully")
end
exit(0)
-----------------------------------------

doesn't work as i expect (it seems the sleep is never called: the
parent process exit immediately after it get SIGCHLD...).

The same script, with the trap commented out work ok (the child
process is a zombie during 20 sec).

And, yes, i know about Process.detach but that's a try to mimic a C
idiom.
 
E

Eric Jacoboni

Timothy Goddard said:
The sleep is called when I run it. What are you trying to achieve?

I expect the parent process sleep during 20 sec... That's not the case:
it exits as soon as it receives SIGCHLD. Did you try to run my script?

If seems that this sleep is interrupted by the SIGCHLD signal, hence
my surprise. Alone, sleep works well.
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Curious interaction between trap and sleep"

|Can someone explain why this code:

<snip>

|doesn't work as i expect (it seems the sleep is never called: the
|parent process exit immediately after it get SIGCHLD...).

It does work on my machine (1.8.4 2006-02-15; i686-linux), although I
have to move trap before fork. Do you mind if I ask you more
information about the version of your Ruby, and your platform?

matz.
 
E

Eric Jacoboni

It does work on my machine (1.8.4 2006-02-15; i686-linux), although I
have to move trap before fork. Do you mind if I ask you more
information about the version of your Ruby, and your platform?

In fact, i realize now it's may be a "no-problem": i was thinking that
sleep(3) was not affected by a signal like SIGCHLD so i didn't
understood why catching this signal make sleep stop working. Now, i
know that sleep is affected by any signal not discarded, so i know why my
script doesn't work as I expected :)

My confusion comes from a C program i've written, equivalent to the
Ruby script: in this C program, the sleep(20) call was sleeping 20 sec
in the parent process, despite a sigaction on SIGCHILD: that was not
the case with my Ruby script, where the sleep function in the parent
process stopped working as soon as the child died, hence my trouble.

Actually, i realize now that it was only a question of timing: in the
C program, SIGCHLD was caught *before* the parent process call
sleep(20): so this sleep was not interrupted. In the Ruby script, a
different timing makes the sleep starting before the child
die... (anyway, that's the conclusion i've reached so far...).

I've tried this script with 1.8.4 both on OS-X (DP ports) and FreeBSD
5.2 and 6.0, with or without pthreads. I've also tried to code the
same thing with Python and Perl (with POSIX module) : both languages
produce the same behaviour than Ruby... so i definitively think the
problem came from my misunderstanding of this timing problem.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top