14

I am writing a server that uses fork() to spawn handlers for client connections. The server does not need to know about what happens to the forked processes – they work on their own, and when they're done, they should just die instead of becoming zombies. What is an easy way to accomplish this?

thejh
  • 44,854
  • 16
  • 96
  • 107
  • 1
    This, probably, is the easiest way: http://stackoverflow.com/questions/7171722/how-can-i-handle-sigchld-in-c/7171836#7171836 – andrewsh Nov 14 '13 at 10:22
  • @andrewsh Oh, nice. Do you think the questions are similar enough to flag this as a duplicate? – thejh Nov 14 '13 at 22:52

3 Answers3

15

There are several ways, but using sigaction with SA_NOCLDWAIT in the parent process is probably the easiest one:

struct sigaction sigchld_action = {
  .sa_handler = SIG_DFL,
  .sa_flags = SA_NOCLDWAIT
};
sigaction(SIGCHLD, &sigchld_action, NULL);
thejh
  • 44,854
  • 16
  • 96
  • 107
7

Use double forks. Have your children immediately fork another copy and have the original child process exit.

http://thinkiii.blogspot.com/2009/12/double-fork-to-avoid-zombie-process.html

This is simpler than using signals, in my opinion, and more understandable.

void safe_fork()
{
  pid_t pid;
  if (!pid=fork()) {
    if (!fork()) {
      /* this is the child that keeps going */
      do_something(); /* or exec */
    } else {
      /* the first child process exits */
      exit(0);
    }
  } else {
    /* this is the original process */  
    /* wait for the first child to exit which it will immediately */
    waitpid(pid);
  }
}
xaxxon
  • 19,189
  • 5
  • 50
  • 80
  • 3
    However, if someone wants to see a process tree or something like that, this will mess it up, right? – thejh Jun 10 '13 at 12:30
  • Not sure, but it seems likely. – xaxxon Jun 10 '13 at 18:08
  • On POSIX systems, the child's parent will be changed to INIT (PID = 1), so yeah, the process tree will not be what you might have expected – Nick Feb 16 '15 at 05:51
  • Is this correct? The fact that the second child process is not becoming a zombie is reliant on the fact that the first child exits immediately. What if do_something() does not do anything? – Curious Mar 12 '16 at 22:26
  • sure you can add some sort of gating mechanism if needed. – xaxxon Mar 12 '16 at 23:05
  • And it works on a per process level and not global. Global configurations are as evil as global variables. – Lothar Jul 21 '16 at 11:02
  • Is that correct that processes don't become zombies but each time the safe_fork() is executed, there's another process in ps which only ends when the parent of all, terminates? – Puffy Jan 30 '18 at 02:40
  • @AbelRomeroPérez They are re-parented to init which cleans them up as soon as they're complete. The short-lived process is cleaned up by the parent process immediately. – xaxxon Jan 30 '18 at 07:46
  • @xaxxon and how can be there's a new process in ps everytime my own implementation of safe_fork() is executed? :( – Puffy Jan 31 '18 at 02:37
0

How to get rid of zombie processes?

you can’t kill the zombie process with SIGKILL signal as you kill a normall process, As the zombie process can’t recive any signal. so having a good habit is very important.

Then when programming, how to get rid amount of zombie processes? According to the above description, the child process will send SIGCHLD signals to the parent process when its dies. by default, this signal is ignored by system, so the best way is that we can call wait() in the signal processing function, which could avoid the zombie stick around in the system. see more about this: http://itsprite.com/how-to-deep-understand-the-zombie-process-in-linux/