SIGCHLD, fork() and sleep()

  • Follow


 Hello,

  I cannot understand this simple situation:

  I ignore SIGCHLD signal and quickly fork N child processes.
  As I ignore SIGCHLD signal the children wont notify the parent
  process of their termination, so no wait() to collect status
  of their termination is needed and no processes should turn into
  Zombies.

  If i quickly fork children processes and quickly exit then after
  the children have terminated and parent is sleep()ing I see a
  single Zombie process.

  If i quickly fork() N children, sleep() in each of the processes
  then after exit()ing them and again sleep()ing in the parent process I
  see N Zombie processes.
  
  As soon as sleep() in the parent process returns Zombie(s) are gone.

  OS - Linux.

  See the source and my comments.

#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#define MAX_CHLD 5

int
main(void)
{
    int i;

    signal(SIGCHLD, SIG_IGN);
    for (i = 0; i < MAX_CHLD; i++) {
        switch(fork()) {
        case -1:
            perror("fork: ");
            exit(EXIT_FAILURE);
        case 0:
            printf("(chld) i = %d\n", i);
            /*
            ** If I sleep() here then after this for(){} loop
            ** terminates and the parent sleep(10)s there will
            ** be MAX_CHLD Zombie processes.
             pkrumins 29014 Z [a <defunct>]
             pkrumins 29015 Z [a <defunct>]
             pkrumins 29016 Z [a <defunct>]
             pkrumins 29017 Z [a <defunct>]
             pkrumins 29018 Z [a <defunct>]
            **
            ** (uncomment this) ->
            sleep(1);
            **
            ** otherwise if I do not sleep() here then
            ** will be a single Zombie process.
            */
            exit(EXIT_SUCCESS);
        }
    }
    /* Here I see Zombies */
    sleep(10);
    /* And here they are gone */
    sleep(3);
    exit(EXIT_SUCCESS);
}


P.Krumins
0
Reply Peteris 1/3/2004 9:25:15 PM

In article <Xns9465EE2DABA6whitesuneapollolv@130.133.1.4>,
 Peteris Krumins <pkruminsREMOVETHIS@inbox.lv> wrote:

>   I ignore SIGCHLD signal and quickly fork N child processes.
>   As I ignore SIGCHLD signal the children wont notify the parent
>   process of their termination, so no wait() to collect status
>   of their termination is needed and no processes should turn into
>   Zombies.
> 
>   If i quickly fork children processes and quickly exit then after
>   the children have terminated and parent is sleep()ing I see a
>   single Zombie process.
> 
>   If i quickly fork() N children, sleep() in each of the processes
>   then after exit()ing them and again sleep()ing in the parent process I
>   see N Zombie processes.
>   
>   As soon as sleep() in the parent process returns Zombie(s) are gone.

It looks like your OS handles ignoring SIGCHLD in the following way: it 
acts as if the parent called wait() when it next runs.  Since the parent 
doesn't run while it's in sleep(), the child processes hang around as 
zombies.  As soon as sleep() returns, the system performs the auto-wait 
and reaps the children.

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
0
Reply Barry 1/4/2004 3:51:05 AM


in comp.unix.programmer i read:

>  I ignore SIGCHLD signal and quickly fork N child processes.
>  As I ignore SIGCHLD signal the children wont notify the parent
>  process of their termination, 

incorrect, the parent is merely ignoring the notifications (made by the
kernel, the children are dead and cannot `do' anything).

>                                so no wait() to collect status
>  of their termination is needed and no processes should turn into
>  Zombies.

incorrect, the children are still dead and since their status has not been
collected they continue to exist as zombies.  when the parent exits these
dead processes will be reparented to pid 1, which will eventually reap
them.

-- 
a signature
0
Reply those 1/4/2004 4:41:36 AM

In article <m1lloo8h0g.gnus@usa.net>,
 those who know me have no need of my name <not-a-real-address@usa.net> 
 wrote:

> in comp.unix.programmer i read:
> 
> >  I ignore SIGCHLD signal and quickly fork N child processes.
> >  As I ignore SIGCHLD signal the children wont notify the parent
> >  process of their termination, 
> 
> incorrect, the parent is merely ignoring the notifications (made by the
> kernel, the children are dead and cannot `do' anything).
> 
> >                                so no wait() to collect status
> >  of their termination is needed and no processes should turn into
> >  Zombies.
> 
> incorrect, the children are still dead and since their status has not been
> collected they continue to exist as zombies.  when the parent exits these
> dead processes will be reparented to pid 1, which will eventually reap
> them.

In many versions of Unix, if you set the handler for SIGCHLD to SIG_IGN, 
the system automatically reaps them -- you don't have to call wait() and 
it doesn't wait until the parent exits.  What he discovered is that 
Linux waits until the parent process runs before it does this.

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
0
Reply Barry 1/4/2004 6:47:33 AM

On 3 Jan 2004 21:25:15 GMT, Peteris Krumins
<pkruminsREMOVETHIS@inbox.lv> wrote:

>
> Hello,

Gidday,

>  I cannot understand this simple situation:

Yes, it's a bit strange...

>  I ignore SIGCHLD signal and quickly fork N child processes.
>  As I ignore SIGCHLD signal the children wont notify the parent
>  process of their termination, so no wait() to collect status
>  of their termination is needed and no processes should turn into
>  Zombies.
>
>  If i quickly fork children processes and quickly exit then after
>  the children have terminated and parent is sleep()ing I see a
>  single Zombie process.

I don't see this -- I wonder if you mean that you are just seeing the
parent process (which is sleeping, not in zombie state).

>  If i quickly fork() N children, sleep() in each of the processes
>  then after exit()ing them and again sleep()ing in the parent process I
>  see N Zombie processes.

Yes, I reproduced this on Linux 2.4.22 with your program.  Strange.  I
haven't checked the source, but things seem to be more or less as
Barry Margolin says...

>  As soon as sleep() in the parent process returns Zombie(s) are gone.

Yes...

So it looks as though in 2.4 things are like this: 

- the SIGCHLD signals are queued to the parent

- only when the parent is next scheduled to run does the kernel then
notice the pending SIGCHLD signals for the parent (this is how signals
are normally processed: -- i.e., on the next swicth from kernel to
user mode in the process's context), and noting that SIG_IGN has been
set as the disposition, then discards the zombies

I tried running your program on 2.6.0, and things behave much more as
we'd both expect: even with your sleep(1), the zombies disappear
immediately (without the parents having to complete it's sleep).

Cheers,

Michael
0
Reply Michael 1/5/2004 9:34:39 AM

Michael Kerrisk <michael-dot-kerrisk-at-gmx-dot-net@NOSPAM.COM> wrote in 
news:0ebivvcst6fc7f04bjiqfdli6ssb4hr92v@4ax.com:


Thanks, everyone who answered!

>>  If i quickly fork children processes and quickly exit then after
>>  the children have terminated and parent is sleep()ing I see a
>>  single Zombie process.
> 
> I don't see this -- I wonder if you mean that you are just seeing the
> parent process (which is sleeping, not in zombie state).

I mean there is a the parent process which Sleeps and a single child
process which is Zombie.
Actually, I tested a second ago, it seems there is a random amount
of Zombie children left if the children processes exit without sleep().

pkrumins 603 S ./b
pkrumins 607 Z [b <defunct>]
pkrumins 608 Z [b <defunct>]

Notice Process 603 is the parent, 604-608 were children and only
the last two staid Zombies.

> 
> I tried running your program on 2.6.0, and things behave much more as
> we'd both expect: even with your sleep(1), the zombies disappear
> immediately (without the parents having to complete it's sleep).
> 

Thanks for looking deeper in the problem.


P.Krumins
0
Reply Peteris 1/6/2004 12:29:32 AM

In article <Xns94681943532Cwhitesuneapollolv@130.133.1.4>,
 Peteris Krumins <pkruminsREMOVETHIS@inbox.lv> wrote:

> Michael Kerrisk <michael-dot-kerrisk-at-gmx-dot-net@NOSPAM.COM> wrote in 
> news:0ebivvcst6fc7f04bjiqfdli6ssb4hr92v@4ax.com:
> 
> 
> Thanks, everyone who answered!
> 
> >>  If i quickly fork children processes and quickly exit then after
> >>  the children have terminated and parent is sleep()ing I see a
> >>  single Zombie process.
> > 
> > I don't see this -- I wonder if you mean that you are just seeing the
> > parent process (which is sleeping, not in zombie state).
> 
> I mean there is a the parent process which Sleeps and a single child
> process which is Zombie.
> Actually, I tested a second ago, it seems there is a random amount
> of Zombie children left if the children processes exit without sleep().

It probably depends on the unpredictable ordering of which processes 
run.  Any children that manage to run to completion before the parent 
gets to its sleep() will be reaped immediately; the ones that are still 
running when the sleep() starts will be reaped when it returns.

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
0
Reply Barry 1/6/2004 2:55:22 AM

On Tue, 06 Jan 2004 02:55:22 GMT, Barry Margolin <barmar@alum.mit.edu>
wrote:

>In article <Xns94681943532Cwhitesuneapollolv@130.133.1.4>,
> Peteris Krumins <pkruminsREMOVETHIS@inbox.lv> wrote:
>
>> Michael Kerrisk <michael-dot-kerrisk-at-gmx-dot-net@NOSPAM.COM> wrote in 
>> news:0ebivvcst6fc7f04bjiqfdli6ssb4hr92v@4ax.com:
>> 
>> 
>> Thanks, everyone who answered!
>> 
>> >>  If i quickly fork children processes and quickly exit then after
>> >>  the children have terminated and parent is sleep()ing I see a
>> >>  single Zombie process.
>> > 
>> > I don't see this -- I wonder if you mean that you are just seeing the
>> > parent process (which is sleeping, not in zombie state).
>> 
>> I mean there is a the parent process which Sleeps and a single child
>> process which is Zombie.
>> Actually, I tested a second ago, it seems there is a random amount
>> of Zombie children left if the children processes exit without sleep().
>
>It probably depends on the unpredictable ordering of which processes 
>run.  Any children that manage to run to completion before the parent 
>gets to its sleep() will be reaped immediately; the ones that are still 
>running when the sleep() starts will be reaped when it returns.

Yes.  And the dufferences that Peteris and I are seeing could be
kernel version dependent.  In some kernel versions (and in some
distributions), Linux has a child-executes-first-after-fork() patch,
while in others, the parent executes first.

Cheers,

Michael
0
Reply Michael 1/7/2004 9:11:31 AM

7 Replies
460 Views

(page loaded in 0.106 seconds)

Similiar Articles:













7/23/2012 1:12:25 AM


Reply: