Forum: Ruby Curious interaction between trap and sleep

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
C5eecd44fa818c7985d4f31bc2c42ac9?d=identicon&s=25 Eric Jacoboni (Guest)
on 2006-02-15 23:30
(Received via mailing list)
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.
Be223e60c56535a0e465b84243aeb0d1?d=identicon&s=25 Timothy Goddard (Guest)
on 2006-02-16 07:00
(Received via mailing list)
The sleep is called when I run it. What are you trying to achieve?
C5eecd44fa818c7985d4f31bc2c42ac9?d=identicon&s=25 Eric Jacoboni (Guest)
on 2006-02-16 11:56
(Received via mailing list)
"Timothy Goddard" <interfecus@gmail.com> writes:

> 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.
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 Yukihiro Matsumoto (Guest)
on 2006-02-17 00:29
(Received via mailing list)
Hi,

In message "Re: Curious interaction between trap and sleep"
    on Thu, 16 Feb 2006 07:28:27 +0900, Eric Jacoboni <jaco@neottia.net>
writes:

|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.
C5eecd44fa818c7985d4f31bc2c42ac9?d=identicon&s=25 Eric Jacoboni (Guest)
on 2006-02-17 01:00
(Received via mailing list)
Yukihiro Matsumoto <matz@ruby-lang.org> writes:


> 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.
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 Yukihiro Matsumoto (Guest)
on 2006-02-17 01:39
(Received via mailing list)
Hi,

In message "Re: Curious interaction between trap and sleep"
    on Fri, 17 Feb 2006 08:58:29 +0900, Eric Jacoboni <jaco@neottia.net>
writes:

|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...).

This is a intended behavior for C program (sleep(3)) but not for Ruby
program, hence it doesn't use sleep(3) and Ruby's sleep method should
always sleep for specified duration.  So I consider this as a bug in
Ruby, and it will be fixed in the next release.  Thank you.

For a work around, put "Thread.start{sleep}" at the head of your
program, #sleep would sleep for specified time amount.

							matz.
This topic is locked and can not be replied to.