views:

283

answers:

3

Hi!

How could I track down the death of a child process without making the parent process wait until the child process got killed?

I am trying a client-server scenario where the server accepts the connection from a client and forks a new process for each and every connection it accepts.

I am ignoring SIGCHLD signals to prevent zombie creation.

signal(SIGCHLD, SIG_IGN);
while(1)
{
  accept();
  clients++;
  if(fork() ==0)
  {
     childfunction();
     clients--;
  }
  else
  {
  }
}

The problem in the above scenario is that if the child process gets killed in the childfunction() function, the global variable clients is not getting decremented.

NOTE: I am looking for a solution without using SIGCHLD signal ... If possible

+8  A: 

Typically you write a handler for SIGCHLD which calls waitpid() on pid -1. You can use the return value from that to determine what pid died. For example:

void my_sigchld_handler(int sig)
{
    pid_t p;
    int status;

    while ((p=waitpid(-1, &status, WNOHANG)) != -1)
    {
       /* Handle the death of pid p */
    }
}

/* It's better to use sigaction() over signal().  You won't run into the
 * issue where BSD signal() acts one way and Linux or SysV acts another. */

struct sigaction sa;

memset(&sa, 0, sizeof(sa));
sa.sa_handler = my_sigchld_handler;

sigaction(SIGCHLD, &sa, NULL);

Alternatively you can call waitpid(pid, &status, 0) with the child's process ID specified, and synchronously wait for it to die. Or use WNOHANG to check its status without blocking.

asveikau
But in my example SIGCHLD is IGNORED ??
codingfreak
@codingfreak And I'm suggesting you might want to re-evaluate that. You don't need to ignore it to avoid zombies. When you `waitpid()` the "zombie" goes away.
asveikau
@asveikau - I am trying to create a daemon process .. and using the SIGCHLD handler broken the stability of the application ..All the time parent process should be waiting down in SIGCHLD handler ..
codingfreak
@codingfreak If it is causing you instability, perhaps you are doing something unsafe in the handler. You have to be careful writing signal handlers because they can be called in the middle of your program where your invariants might be temporary broken. Check out a Google search for "posix signal safety" or something.
asveikau
This is *precisely* what the `SIGCHLD` signal is for.
caf
@asveikau - Tried using the SIGCHLD in my application and it is not cleaning the zombies properly. .. Just check my question as I updated with my sample app.
codingfreak
caf
A: 
jschmier
After changes made as you said .. I dont see any zombies created .. Let me see how it behaves in HTTP server daemon ...
codingfreak
I don't anticipate any major problems with using this code in your daemon.
jschmier
A: 

The variable 'clients' are in different process address spaces after fork() and when you decrement the variable in the child, this will not affect the value in the parent. I think you need to handle SIGCHLD to handle the count correctly.

trojanfoe