# Curious interaction between trap and sleep

**URL:** <https://www.ruby-forum.com/t/curious-interaction-between-trap-and-sleep/68944>\
**Category:** Ruby\
**Created:** [February 15, 2006, 11:30pm UTC](https://www.ruby-forum.com/t/curious-interaction-between-trap-and-sleep/68944 "2006-02-15T23:30:12Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![cowboy\_x](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/d78d45/32.png) [@cowboy\_x](https://www.ruby-forum.com/u/cowboy_x)\
**Post date:** [February 15, 2006, 11:30pm UTC](https://www.ruby-forum.com/t/curious-interaction-between-trap-and-sleep/68944/1 "2006-02-15T23:30:12Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![cowboy\_x](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/d78d45/32.png) [@cowboy\_x](https://www.ruby-forum.com/u/cowboy_x)\
**Post date:** [February 16, 2006, 7:00am UTC](https://www.ruby-forum.com/t/curious-interaction-between-trap-and-sleep/68944/2 "2006-02-16T07:00:37Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![cowboy\_x](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/d78d45/32.png) [@cowboy\_x](https://www.ruby-forum.com/u/cowboy_x)\
**Post date:** [February 16, 2006, 11:56am UTC](https://www.ruby-forum.com/t/curious-interaction-between-trap-and-sleep/68944/3 "2006-02-16T11:56:25Z")

</div>

“Timothy G.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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.

---

<div class="post-metadata">

**Author:** ![cowboy\_x](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/d78d45/32.png) [@cowboy\_x](https://www.ruby-forum.com/u/cowboy_x)\
**Post date:** [February 17, 2006, 12:29am UTC](https://www.ruby-forum.com/t/curious-interaction-between-trap-and-sleep/68944/4 "2006-02-17T00:29:49Z")

</div>

Hi,

In message “Re: Curious interaction between trap and sleep”  
on Thu, 16 Feb 2006 07:28:27 +0900, Eric J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
writes:

|Can someone explain why this code:

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

```

---

<div class="post-metadata">

**Author:** ![cowboy\_x](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/d78d45/32.png) [@cowboy\_x](https://www.ruby-forum.com/u/cowboy_x)\
**Post date:** [February 17, 2006, 1:00am UTC](https://www.ruby-forum.com/t/curious-interaction-between-trap-and-sleep/68944/5 "2006-02-17T01:00:11Z")

</div>

Yukihiro M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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.

---

<div class="post-metadata">

**Author:** ![cowboy\_x](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/d78d45/32.png) [@cowboy\_x](https://www.ruby-forum.com/u/cowboy_x)\
**Post date:** [February 17, 2006, 1:39am UTC](https://www.ruby-forum.com/t/curious-interaction-between-trap-and-sleep/68944/6 "2006-02-17T01:39:34Z")

</div>

Hi,

In message “Re: Curious interaction between trap and sleep”  
on Fri, 17 Feb 2006 08:58:29 +0900, Eric J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
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.

```
