Professional Web Applications Themes

SIGCHLD, fork() and sleep() - UNIX Programming

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

  1. #1

    Default SIGCHLD, fork() and sleep()


    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
    Peteris Guest

  2. #2

    Default Re: SIGCHLD, fork() and sleep()

    In article <133.1.4>,
    Peteris Krumins <lv> wrote:
     

    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, mit.edu
    Arlington, MA
    Barry Guest

  3. #3

    Default Re: SIGCHLD, fork() and sleep()

    in comp.unix.programmer i read:
     

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

    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
    those Guest

  4. #4

    Default Re: SIGCHLD, fork() and sleep()

    In article <net>,
    those who know me have no need of my name <net>
    wrote:
     
    >
    > incorrect, the parent is merely ignoring the notifications (made by the
    > kernel, the children are dead and cannot `do' anything).

    >
    > 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.[/ref]

    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, mit.edu
    Arlington, MA
    Barry Guest

  5. #5

    Default Re: SIGCHLD, fork() and sleep()

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

    Gidday,
     

    Yes, it's a bit strange...
     

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

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

    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
    Michael Guest

  6. #6

    Default Re: SIGCHLD, fork() and sleep()

    Michael Kerrisk <COM> wrote in
    news:com:


    Thanks, everyone who answered!
     
    >
    > 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).[/ref]

    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.
     

    Thanks for looking deeper in the problem.


    P.Krumins
    Peteris Guest

  7. #7

    Default Re: SIGCHLD, fork() and sleep()

    In article <133.1.4>,
    Peteris Krumins <lv> wrote:
     
    > >
    > > 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).[/ref]
    >
    > 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().[/ref]

    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, mit.edu
    Arlington, MA
    Barry Guest

  8. #8

    Default Re: SIGCHLD, fork() and sleep()

    On Tue, 06 Jan 2004 02:55:22 GMT, Barry Margolin <mit.edu>
    wrote:
     
    >>
    >> 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().[/ref]
    >
    >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.[/ref]

    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
    Michael Guest

Similar Threads

  1. fork() race in SIGCHLD handler
    By Chris in forum UNIX Programming
    Replies: 18
    Last Post: January 4th, 05:39 PM
  2. SIGINT, SIGCHLD, and free()
    By Aaron in forum UNIX Programming
    Replies: 5
    Last Post: November 25th, 12:03 PM
  3. fork not available?
    By walter@mwsewall.com in forum Ruby
    Replies: 22
    Last Post: September 23rd, 02:56 PM
  4. memory and fork
    By Peteris in forum UNIX Programming
    Replies: 3
    Last Post: September 22nd, 10:12 PM
  5. Pthreads and SIGCHLD
    By Chris in forum UNIX Programming
    Replies: 5
    Last Post: September 11th, 08:57 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139