fork/exec/waitpid/SIGCHLD/zombie - design && implementation question - Unix

This is a discussion on fork/exec/waitpid/SIGCHLD/zombie - design && implementation question - Unix ; Hello Have several question related to the process execution First of all - what do I have There are one multithreaded application and one shared object (application is linked against this shared object) Both application and shared object execute external ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: fork/exec/waitpid/SIGCHLD/zombie - design && implementation question

  1. fork/exec/waitpid/SIGCHLD/zombie - design && implementation question

    Hello

    Have several question related to the process execution

    First of all - what do I have

    There are one multithreaded application and one shared object
    (application is linked against this shared object)
    Both application and shared object execute external programs...

    Meta code from shared object:
    executeChild()
    {
    fork();
    if (childProcess) exec();
    else waitpid(childProcess);
    }

    Main application has next code inside:
    executeSubProcess()
    {
    installs child handler
    run(fork/exec) a dozen of child processes
    }

    Signal handler from main application does next:
    signalHandler()
    {
    wait();
    reinstallSignalHandler();
    }

    Recently, I have detected a problem that sometimes I have zombie on
    processes started from main application.
    Search on google directed me to the Steven's Advanced Programming on
    Unix Environment...
    He says that correct version would look like
    signalHandler()
    {
    while(wait()>0);
    reinstallSignalHandler();
    }

    Now, after reading Stevens I have a few questions related to design of
    the application
    1. Is it correct to do fork/exec not only in the main application, but
    also in shared object either?
    2. Is it OK to do wait/waitpid not only in signal handler, but in
    other places too?
    3. Wouldn't wait()/waitpid() system calls from shared object and main
    application interfere one with another? (eg - executeChild() will wait
    for termination of its child till eternity, cause it would be
    processed by signalHandler() from main module)
    4. Sometimes (but very RARE) I see zombie processes which were
    executed from shared object (executeChild). What could be wrong in
    this case?

    If design is wrong, and this should be redesigned - could you please
    advice better solutions?

    Tx in advance,
    Alexandru


  2. Re: fork/exec/waitpid/SIGCHLD/zombie - design && implementation question

    Hello Alexandru,

    > Recently, I have detected a problem that sometimes I have zombie on
    > processes started from main application.
    > Search on google directed me to the Steven's Advanced Programming on
    > Unix Environment...
    > He says that correct version would look like
    > signalHandler()
    > {
    > while(wait()>0);
    > reinstallSignalHandler();
    >
    > }


    Perhaps it is a wild guess, but the reason might be that you may get
    less SIGCLHD as you have dead children waiting to be reaped.

    You should set the signal handler for SIGCHLD using sigaction(). Then
    you should basically loop in the signal handler using waipid() with
    the WNOHANG flag:

    void signalHandler(int signo)
    {
    int status;
    pid_t pid;
    int saveerrno = errno;

    while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
    /* do whatever you want to do with PID and STATUS */;

    errno = saveerrno;
    }

    BTW, there is an update revision of Stevens APUE book:
    http://www.apuebook.com/

    HTH,
    Loic.


  3. Re: fork/exec/waitpid/SIGCHLD/zombie - design && implementation question

    Hello Loic,

    On Nov 12, 8:22 pm, Loic Domaigne wrote:
    > Hello Alexandru,
    >
    > > Recently, I have detected a problem that sometimes I have zombie on
    > > processes started from main application.
    > > Search on google directed me to the Steven's Advanced Programming on
    > > Unix Environment...
    > > He says that correct version would look like
    > > signalHandler()
    > > {
    > > while(wait()>0);
    > > reinstallSignalHandler();

    >
    > > }

    >
    > Perhaps it is a wild guess, but the reason might be that you may get
    > less SIGCLHD as you have dead children waiting to be reaped.
    >
    > You should set the signal handler for SIGCHLD using sigaction(). Then
    > you should basically loop in the signal handler using waipid() with
    > the WNOHANG flag:
    >
    > void signalHandler(int signo)
    > {
    > int status;
    > pid_t pid;
    > int saveerrno = errno;
    >
    > while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
    > /* do whatever you want to do with PID and STATUS */;
    >
    > errno = saveerrno;
    >
    > }
    >
    > BTW, there is an update revision of Stevens APUE book:http://www.apuebook.com/


    Thank you Loic - this is exactly I want to do after I have read
    Stevens' APUE

    But my question mostly are related to the design
    Cause it is a pretty old code - and may be it is time to redesign
    it

    1. Is it correct to do fork/exec not only in the main application, but
    also in shared object either?
    2. Is it OK to do wait/waitpid not only in signal handler, but in
    other places too?
    3. Wouldn't wait()/waitpid() system calls from shared object and main
    application interfere one with another? (eg - executeChild() will wait
    for termination of its child till eternity, cause it would be
    processed by signalHandler() from main module)
    4. Sometimes (but very RARE) I see zombie processes which were
    executed from shared object (executeChild). What could be wrong in
    this case?

    If design is wrong, and this should be redesigned - could you please
    advice better solutions?

    > HTH,
    > Loic.


    Tx,
    Alexandru


  4. Re: fork/exec/waitpid/SIGCHLD/zombie - design && implementation question

    In article <1194902483.930647.162400@50g2000hsm.googlegroups.c om>,
    asclearuc@gmail.com wrote:

    > Hello Loic,
    >
    > On Nov 12, 8:22 pm, Loic Domaigne wrote:
    > > Hello Alexandru,
    > >
    > > > Recently, I have detected a problem that sometimes I have zombie on
    > > > processes started from main application.
    > > > Search on google directed me to the Steven's Advanced Programming on
    > > > Unix Environment...
    > > > He says that correct version would look like
    > > > signalHandler()
    > > > {
    > > > while(wait()>0);
    > > > reinstallSignalHandler();

    > >
    > > > }

    > >
    > > Perhaps it is a wild guess, but the reason might be that you may get
    > > less SIGCLHD as you have dead children waiting to be reaped.
    > >
    > > You should set the signal handler for SIGCHLD using sigaction(). Then
    > > you should basically loop in the signal handler using waipid() with
    > > the WNOHANG flag:
    > >
    > > void signalHandler(int signo)
    > > {
    > > int status;
    > > pid_t pid;
    > > int saveerrno = errno;
    > >
    > > while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
    > > /* do whatever you want to do with PID and STATUS */;
    > >
    > > errno = saveerrno;
    > >
    > > }
    > >
    > > BTW, there is an update revision of Stevens APUE
    > > book:http://www.apuebook.com/

    >
    > Thank you Loic - this is exactly I want to do after I have read
    > Stevens' APUE
    >
    > But my question mostly are related to the design
    > Cause it is a pretty old code - and may be it is time to redesign
    > it
    >
    > 1. Is it correct to do fork/exec not only in the main application, but
    > also in shared object either?


    I think you're actually asking whether it's OK to do it in a library
    function. Whether it's statically or dynamically linked is irrelevant
    to program design.

    It's considered OK. The library function system() performs a
    fork/exec/waitpid. However, see below for the care that you have to
    take to prevent interference.

    > 2. Is it OK to do wait/waitpid not only in signal handler, but in
    > other places too?
    > 3. Wouldn't wait()/waitpid() system calls from shared object and main
    > application interfere one with another? (eg - executeChild() will wait
    > for termination of its child till eternity, cause it would be
    > processed by signalHandler() from main module)


    This is why the system() function is required to block SIGCHLD. It has
    to use waitpid() to wait for its child synchronously, so that it doesn't
    interfere with the rest of the application. The fact that system() uses
    a child process is intended to be transparent.

    > 4. Sometimes (but very RARE) I see zombie processes which were
    > executed from shared object (executeChild). What could be wrong in
    > this case?


    That's hard to tell from the pseudo-code -- it looks reasonable.

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

+ Reply to Thread