How to avoid zombie processes? - Unix

This is a discussion on How to avoid zombie processes? - Unix ; The APUE section 8.6 mentions a method to avoid zombie processes. The trick is to call fork twice: #include "apue.h" #include int main(void) { pid_t pid; if ((pid = fork()) err_sys("fork error"); } else if (pid == 0) { if ...

+ Reply to Thread
Results 1 to 19 of 19

Thread: How to avoid zombie processes?

  1. How to avoid zombie processes?

    The APUE section 8.6 mentions a method to avoid zombie processes.
    The trick is to call fork twice:

    #include "apue.h"
    #include

    int main(void)
    {
    pid_t pid;
    if ((pid = fork()) < 0) {
    err_sys("fork error");
    } else if (pid == 0) {
    if ((pid = fork()) < 0)
    err_sys("fork error");
    else if (pid > 0)
    exit(0);

    sleep(2);
    printf("second child, parent pid = %d\n", getpid());
    exit(0);
    }

    if (waitpid(pid, NULL, 0) != pid)
    err_sys("waitpid error");

    exit(0);
    }

    But I cannot understand why this code could avoid zombie.
    Can you explain it?

  2. Re: How to avoid zombie processes?

    On Sep 12, 6:33*pm, Lambda wrote:
    > The APUE section 8.6 mentions a method to avoid zombie processes.
    > The trick is to call fork twice:

    [snip]
    > But I cannot understand why this code could avoid zombie.
    > Can you explain it?


    Since your child dies immediately after creation, and you reap it,
    there is no child *of* *yours* left around to become a zombie.

    DS



  3. Re: How to avoid zombie processes?

    In article
    <31fc09cd-4b1f-4650-a61a-05144b3f692b@s9g2000prg.googlegroups.com>,
    Lambda wrote:

    > The APUE section 8.6 mentions a method to avoid zombie processes.
    > The trick is to call fork twice:
    >
    > #include "apue.h"
    > #include
    >
    > int main(void)
    > {
    > pid_t pid;
    > if ((pid = fork()) < 0) {
    > err_sys("fork error");
    > } else if (pid == 0) {
    > if ((pid = fork()) < 0)
    > err_sys("fork error");
    > else if (pid > 0)
    > exit(0);
    >
    > sleep(2);
    > printf("second child, parent pid = %d\n", getpid());
    > exit(0);
    > }
    >
    > if (waitpid(pid, NULL, 0) != pid)
    > err_sys("waitpid error");
    >
    > exit(0);
    > }
    >
    > But I cannot understand why this code could avoid zombie.
    > Can you explain it?


    When a process's parent terminates, the "init" process takes over as its
    parent. So when the child process exits, the grandchild loses its
    parent, and is adopted by init. Init always reaps its dead children, so
    they don't become zombies.

    --
    Barry Margolin, barmar@alum.mit.edu
    Arlington, MA
    *** PLEASE post questions in newsgroups, not directly to me ***
    *** PLEASE don't copy me on replies, I'll read them in the group ***

  4. Re: How to avoid zombie processes?

    On Sep 13, 10:53*am, Barry Margolin wrote:
    > In article
    > <31fc09cd-4b1f-4650-a61a-05144b3f6...@s9g2000prg.googlegroups.com>,
    >
    >
    >
    > *Lambda wrote:
    > > The APUE section 8.6 mentions a method to avoid zombie processes.
    > > The trick is to call fork twice:

    >
    > > #include "apue.h"
    > > #include

    >
    > > int main(void)
    > > {
    > > * pid_t pid;
    > > * if ((pid = fork()) < 0) {
    > > * * err_sys("fork error");
    > > * } else if (pid == 0) {
    > > * * * if ((pid = fork()) < 0)
    > > * * * * err_sys("fork error");
    > > * * * else if (pid > 0)
    > > * * * * exit(0);

    >
    > > * * * sleep(2);
    > > * * * printf("second child, parent pid = %d\n", getpid());
    > > * * * exit(0);
    > > * }

    >
    > > * if (waitpid(pid, NULL, 0) != pid)
    > > * * err_sys("waitpid error");

    >
    > > * exit(0);
    > > }

    >
    > > But I cannot understand why this code could avoid zombie.
    > > Can you explain it?

    >
    > When a process's parent terminates, the "init" process takes over as its
    > parent. *So when the child process exits, the grandchild loses its
    > parent, and is adopted by init. *Init always reaps its dead children, so
    > they don't become zombies.
    >
    > --
    > Barry Margolin, bar...@alum.mit.edu
    > Arlington, MA
    > *** PLEASE post questions in newsgroups, not directly to me ***
    > *** PLEASE don't copy me on replies, I'll read them in the group ***


    Thank you for your reply!

    I'm new to unix programming. And I have one more question:
    There are 3 processes here: parent, child, grandchild.

    If the parent terminate before the child, and init inherit the child,
    the child will not become a zombie, so why we need the grandchild?

    If the child terminate before the parent, the parent will wait() the
    child.
    the child will not become a zombie.

    So in what situations, the child will become a zombie?
    If I don't make mistakes, is the zombie possible?

  5. Re: How to avoid zombie processes?

    On 2008-09-15, Lambda wrote:
    > I'm new to unix programming. And I have one more question:
    > There are 3 processes here: parent, child, grandchild.
    >
    > If the parent terminate before the child, and init inherit the child,
    > the child will not become a zombie, so why we need the grandchild?


    It's useful if you don't want the parent to terminate, and you don't
    intend to wait either.

    > If the child terminate before the parent, the parent will wait() the
    > child.
    > the child will not become a zombie.


    Indeed, if the parent waits (say on SIGCHLD) the child will not become a
    zombie.

    > So in what situations, the child will become a zombie?


    The child becomes a zombie after it terminates, if its parent is still
    alive, and it doesn't call wait. Until the parent calls wait, or the
    parent exits, and the child is inherited by init, the child remains a
    zombie.

    By using the double-fork trick, the child (well, the grandchild really)
    is immediately inherited by init, so it can never become a zombie (and
    you can never retrieve its exit code either).

    --
    John Tsiombikas (Nuclear / Mindlapse)
    http://nuclear.sdf-eu.org/

  6. Re: How to avoid zombie processes?

    On Sep 15, 5:11*pm, John Tsiombikas wrote:
    > On 2008-09-15, Lambda wrote:
    >
    > > I'm new to unix programming. And I have one more question:
    > > There are 3 processes here: parent, child, grandchild.

    >
    > > If the parent terminate before the child, and init inherit the child,
    > > the child will not become a zombie, so why we need the grandchild?

    >
    > It's useful if you don't want the parent to terminate, and you don't
    > intend to wait either.
    >
    > > If the child terminate before the parent, the parent will wait() the
    > > child.
    > > the child will not become a zombie.

    >
    > Indeed, if the parent waits (say on SIGCHLD) the child will not become a
    > zombie.
    >
    > > So in what situations, the child will become a zombie?

    >
    > The child becomes a zombie after it terminates, if its parent is still
    > alive, and it doesn't call wait. Until the parent calls wait, or the
    > parent exits, and the child is inherited by init, the child remains a
    > zombie.
    >
    > By using the double-fork trick, the child (well, the grandchild really)
    > is immediately inherited by init, so it can never become a zombie (and
    > you can never retrieve its exit code either).
    >
    > --
    > John Tsiombikas (Nuclear / Mindlapse)http://nuclear.sdf-eu.org/


    Thank you!

    Is my understanding right?

    Without the trick, if the child terminate, and at the moment,
    the parent doesn't call wait(), so the child become zombie,
    a little later, the parent calls wait(), the child process is not
    a zombie any more and disappear in the ps command.
    So, there IS a zombie, for a short period of time.

    With this trick, there is NO zombie, even for a short period of time.

    Short life zombies will not do harm to the system, right?
    We only need to make sure there is no zombie whose life is too long,
    right?

  7. Re: How to avoid zombie processes?

    >> I'm new to unix programming. And I have one more question:
    >> There are 3 processes here: parent, child, grandchild.
    >>
    >> If the parent terminate before the child, and init inherit the child,
    >> the child will not become a zombie, so why we need the grandchild?


    The child will *always* become a zombie, at least briefly, when
    it terminates.

    >It's useful if you don't want the parent to terminate, and you don't
    >intend to wait either.
    >
    >> If the child terminate before the parent, the parent will wait() the
    >> child.
    >> the child will not become a zombie.

    >
    >Indeed, if the parent waits (say on SIGCHLD) the child will not become a
    >zombie.


    The child will *always* become a zombie, at least briefly, when
    it terminates.

    >> So in what situations, the child will become a zombie?


    When it exits. It may stay a zombie for a considerable period of
    time if its parent (or adoptive parent) is not currently wait()ing
    for it.

    Note that you can have a *lot* of zombies if "init" (process 1)
    gets hung up and quits waiting. The best thing for this situation
    is to shut down quickly and reboot.

    >The child becomes a zombie after it terminates, if its parent is still
    >alive, and it doesn't call wait. Until the parent calls wait, or the
    >parent exits, and the child is inherited by init, the child remains a
    >zombie.
    >
    >By using the double-fork trick, the child (well, the grandchild really)
    >is immediately inherited by init, so it can never become a zombie (and
    >you can never retrieve its exit code either).


    A process will always become a zombie when it terminates, at least
    briefly.


  8. Re: How to avoid zombie processes?

    On 15 Sep, 10:47, Lambda wrote:
    >
    > Without the trick, if the child terminate, and at the moment,
    > the parent doesn't call wait(), so the child become zombie,
    > a little later, the parent calls wait(), the child process is not
    > a zombie any more and disappear in the ps command.
    > So, there IS a zombie, for a short period of time.
    >
    > With this trick, there is NO zombie, even for a short period of time.


    No. Every process that exits is a zombie until its parent
    waits for it. If the parent of the process is init, the amount
    of time during which the process is in the zombie state
    is probably very short, but it is not non-zero. The only
    purpose of the double-fork technique is to make init the
    parent of the process you care about, based on the
    premise that init is unlikely to have many bugs that
    cause it to fail to reap its children quickly.


  9. Re: How to avoid zombie processes?

    In article
    ,
    William Pursell wrote:

    > On 15 Sep, 10:47, Lambda wrote:
    > >
    > > Without the trick, if the child terminate, and at the moment,
    > > the parent doesn't call wait(), so the child become zombie,
    > > a little later, the parent calls wait(), the child process is not
    > > a zombie any more and disappear in the ps command.
    > > So, there IS a zombie, for a short period of time.
    > >
    > > With this trick, there is NO zombie, even for a short period of time.

    >
    > No. Every process that exits is a zombie until its parent
    > waits for it. If the parent of the process is init, the amount
    > of time during which the process is in the zombie state
    > is probably very short, but it is not non-zero. The only
    > purpose of the double-fork technique is to make init the
    > parent of the process you care about, based on the
    > premise that init is unlikely to have many bugs that
    > cause it to fail to reap its children quickly.


    IMHO, the purpose of the double-fork technique is just to simplify
    programming. The parent process can call wait synchronously, right
    after forking the child; it doesn't have to worry about this delaying
    the program very long, because the child is going to fork right away and
    then exit. For most practical purposes, it's an instantaneous operation.

    Without this technique, the parent process typically has to establish a
    SIGCHLD handler so it will be notified when the child terminates and it
    needs to call wait(). Also, if you spawn multiple children you have to
    worry about calling wait() in a loop to reap all of them. Although this
    isn't rocket science, it's unnecessary complications if you don't
    actually care about the exit status of the child.

    The double-fork technique is not needed in some cases, though, such as:

    1) The parent process exits shortly after forking, as when a process
    becomes a daemon.

    2) The parent doesn't need to do anything in parallel with the child, so
    it can wait synchronously for it to exit. The system() function is like
    this.

    --
    Barry Margolin, barmar@alum.mit.edu
    Arlington, MA
    *** PLEASE post questions in newsgroups, not directly to me ***
    *** PLEASE don't copy me on replies, I'll read them in the group ***

  10. Re: How to avoid zombie processes?

    On Sep 15, 11:47 am, Lambda wrote:

    [...]
    > Short life zombies will not do harm to the system, right?
    > We only need to make sure there is no zombie whose life is too long,
    > right?


    Zombies, per se, don't hurt the system, regardless of how long
    they live. A zombie, however, does consume resources. For
    nothing, since it doesn't do anything. If you have a long lived
    process which continually spawns child processes, and neither
    waits for them nor arranges for some other process (like init)
    to wait for them, you will eventually run out of resources.

    --
    James Kanze (GABI Software) email:james.kanze@gmail.com
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

  11. Re: How to avoid zombie processes?

    On Sep 15, 6:07*pm, Barry Margolin wrote:

    > IMHO, the purpose of the double-fork technique is just to simplify
    > programming. *The parent process can call wait synchronously, right
    > after forking the child; it doesn't have to worry about this delaying
    > the program very long, because the child is going to fork right away and
    > then exit. *For most practical purposes, it's an instantaneous operation.


    I agree.

    > Without this technique, the parent process typically has to establish a
    > SIGCHLD handler so it will be notified when the child terminates and it
    > needs to call wait(). *Also, if you spawn multiple children you have to
    > worry about calling wait() in a loop to reap all of them. *Although this
    > isn't rocket science, it's unnecessary complications if you don't
    > actually care about the exit status of the child.


    This can be a real problem if the code that creates the child is in a
    library. It's also tricky when it's part of any program where not all
    the code is designed as a unit. You don't want to have code that, if
    you ever call it, imposes restrictions on what your program has to do
    for the rest of its life.

    DS

  12. Re: How to avoid zombie processes?

    On 2008-09-15, Gordon Burditt wrote:
    >>> If the child terminate before the parent, the parent will wait() the
    >>> child.
    >>> the child will not become a zombie.

    >>
    >>Indeed, if the parent waits (say on SIGCHLD) the child will not become a
    >>zombie.

    >
    > The child will *always* become a zombie, at least briefly, when
    > it terminates.


    Yes of course, what I meant rather, was that "in that case you don't
    have to worry about it" since it will not stay and consume a process
    table entry and other bits of memory for process statistics, accounting,
    exit codes, whatever for too long. The "problematic" zombies are the
    ones that stay in that state for a long time.

    --
    John Tsiombikas (Nuclear / Mindlapse)
    http://nuclear.sdf-eu.org/

  13. Re: How to avoid zombie processes?

    In article ,
    John Tsiombikas wrote:

    > On 2008-09-15, Gordon Burditt wrote:
    > >>> If the child terminate before the parent, the parent will wait() the
    > >>> child.
    > >>> the child will not become a zombie.
    > >>
    > >>Indeed, if the parent waits (say on SIGCHLD) the child will not become a
    > >>zombie.

    > >
    > > The child will *always* become a zombie, at least briefly, when
    > > it terminates.

    >
    > Yes of course, what I meant rather, was that "in that case you don't
    > have to worry about it" since it will not stay and consume a process
    > table entry and other bits of memory for process statistics, accounting,
    > exit codes, whatever for too long. The "problematic" zombies are the
    > ones that stay in that state for a long time.


    More precisely, it's generally only a problem if you create LOTS of
    zombies. E.g. if a server forks a child for every client, but never
    reaps them when they exit, you may eventually fill up the process table
    with zombies.

    On the other hand, if a program only forks a single child, and it
    becomes a zombie, it's not likely to be a problem. The zombie will go
    away when the program finishes. This would probably only become a
    problem if you ran many concurrent copies of the program, and they run
    for a long time, since half the processes would be zombies.

    But the simple double-fork technique makes it easy to avoid any of these
    problems. After all these years, I'm surprised POSIX hasn't instituted
    a simple fork2() API that encapsulates it.

    --
    Barry Margolin, barmar@alum.mit.edu
    Arlington, MA
    *** PLEASE post questions in newsgroups, not directly to me ***
    *** PLEASE don't copy me on replies, I'll read them in the group ***

  14. Re: How to avoid zombie processes?

    Barry Margolin writes:
    > In article ,
    > John Tsiombikas wrote:


    [...]

    >> Yes of course, what I meant rather, was that "in that case you don't
    >> have to worry about it" since it will not stay and consume a process
    >> table entry and other bits of memory for process statistics, accounting,
    >> exit codes, whatever for too long. The "problematic" zombies are the
    >> ones that stay in that state for a long time.

    >
    > More precisely, it's generally only a problem if you create LOTS of
    > zombies. E.g. if a server forks a child for every client, but never
    > reaps them when they exit, you may eventually fill up the process table
    > with zombies.
    >
    > On the other hand, if a program only forks a single child, and it
    > becomes a zombie, it's not likely to be a problem. The zombie will go
    > away when the program finishes. This would probably only become a
    > problem if you ran many concurrent copies of the program, and they run
    > for a long time, since half the processes would be zombies.


    The other situation would be that lots of programs which create one
    (or maybe two) zombies are running concurrently.

    > But the simple double-fork technique makes it easy to avoid any of these
    > problems. After all these years, I'm surprised POSIX hasn't instituted
    > a simple fork2() API that encapsulates it.


    It is (should be) possible to explicitly set the dispositon for
    SIGCHLD to SIG_IGN instead, avoiding the need to create an
    intermediate process and wait for its termination in the original
    parent.


  15. Re: How to avoid zombie processes?

    In article <87wsh9g64w.fsf@fever.mssgmbh.com>,
    Rainer Weikusat wrote:

    > It is (should be) possible to explicitly set the dispositon for
    > SIGCHLD to SIG_IGN instead, avoiding the need to create an
    > intermediate process and wait for its termination in the original
    > parent.
    >


    I recall that this is implementation-dependent. Has it been
    standardized in POSIX?

    --
    Barry Margolin, barmar@alum.mit.edu
    Arlington, MA
    *** PLEASE post questions in newsgroups, not directly to me ***
    *** PLEASE don't copy me on replies, I'll read them in the group ***

  16. Re: How to avoid zombie processes?

    Barry Margolin writes:
    > Rainer Weikusat wrote:
    >> It is (should be) possible to explicitly set the dispositon for
    >> SIGCHLD to SIG_IGN instead, avoiding the need to create an
    >> intermediate process and wait for its termination in the original
    >> parent.
    >>

    >
    > I recall that this is implementation-dependent. Has it been
    > standardized in POSIX?


    As XSI-extension (to be found in the SIG_IGN section of the 'signal
    concepts' page).

  17. Re: How to avoid zombie processes?

    In article <874p4c2zgb.fsf@fever.mssgmbh.com>,
    Rainer Weikusat wrote:

    > Barry Margolin writes:
    > > Rainer Weikusat wrote:
    > >> It is (should be) possible to explicitly set the dispositon for
    > >> SIGCHLD to SIG_IGN instead, avoiding the need to create an
    > >> intermediate process and wait for its termination in the original
    > >> parent.
    > >>

    > >
    > > I recall that this is implementation-dependent. Has it been
    > > standardized in POSIX?

    >
    > As XSI-extension (to be found in the SIG_IGN section of the 'signal
    > concepts' page).


    In other words, they documented that this is implementation-dependent.
    Since it's only an extension, you can't depend on it for maximum
    portability, so you're usually better off using the double-fork trick.

    --
    Barry Margolin, barmar@alum.mit.edu
    Arlington, MA
    *** PLEASE post questions in newsgroups, not directly to me ***
    *** PLEASE don't copy me on replies, I'll read them in the group ***

  18. Re: How to avoid zombie processes?

    Barry Margolin writes:
    > Rainer Weikusat wrote:
    >> Barry Margolin writes:
    >> > Rainer Weikusat wrote:
    >> >> It is (should be) possible to explicitly set the dispositon for
    >> >> SIGCHLD to SIG_IGN instead, avoiding the need to create an
    >> >> intermediate process and wait for its termination in the original
    >> >> parent.
    >> >>
    >> >
    >> > I recall that this is implementation-dependent. Has it been
    >> > standardized in POSIX?

    >>
    >> As XSI-extension (to be found in the SIG_IGN section of the 'signal
    >> concepts' page).

    >
    > In other words, they documented that this is
    > implementation-dependent. Since it's only an extension, you can't
    > depend on it for maximum portability, so you're usually better off
    > using the double-fork trick.


    You cannot depend on any SUS-functionality without verifying that it
    is actually supported by some set of 'interesting implementations'
    first, because the properties of all implementations are
    'implementation dependent'. Especially, since more systems claim to be
    somewhat conformant to some SUS-subset than are certified to be
    conformant (eg Linux or QNX). But that is IMO a weak excuse for having
    worse support for any particular 'interesting implementation' than
    would (fairly easily) be possible.

    IOW, "why am I still forced to chase Netscape lockfiles because of
    rumours about 'broken' rpc.lockd-implementations having been in use
    somewhere ten years ago"?

  19. Re: How to avoid zombie processes?

    Why we have called waitpid in the end ?? the argument pid in that function stands for the process id of the child for which parent is waiting to terminate or parent want the termination status of child whose process ID is pid ?????

+ Reply to Thread