fork出子进程后父进程并不想关心子进程了,也不想费心wait,自顾自的继续执行自己的代码,之后子进程退出时会变成僵尸进程。要避免产生僵尸进程,使用sigaction函数设置SIGCHLD信号处理,并设置sa_flags 为 SA_NOCLDWAIT,man sigaction可见SA_NOCLDWAIT描述:
SA_NOCLDWAIT (Since Linux 2.6)
If signum is SIGCHLD, do not transform children into zombies when they terminate. See also waitpid(2). This flag is only mean-
ingful when establishing a handler for SIGCHLD, or when setting that signal’s disposition to SIG_DFL.
If the SA_NOCLDWAIT flag is set when establishing a handler for SIGCHLD, POSIX.1 leaves it unspecified whether a SIGCHLD signal is
generated when a child process terminates. On Linux, a SIGCHLD signal is generated in this case; on some other implementations,
it is not.
If signum is SIGCHLD, do not transform children into zombies when they terminate. See also waitpid(2). This flag is only mean-
ingful when establishing a handler for SIGCHLD, or when setting that signal’s disposition to SIG_DFL.
If the SA_NOCLDWAIT flag is set when establishing a handler for SIGCHLD, POSIX.1 leaves it unspecified whether a SIGCHLD signal is
generated when a child process terminates. On Linux, a SIGCHLD signal is generated in this case; on some other implementations,
it is not.
代码测试如下:
1 #include <unistd.h> 2 #include <signal.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 6 int main(int argc, char *argv[]) { 7 struct sigaction act; 8 act.sa_handler = SIG_DFL; 9 act.sa_flags = SA_NOCLDWAIT; 10 if (sigaction(SIGCHLD, &act, NULL) < 0) { 11 perror("sigaction"); 12 return -1; 13 } 14 pid_t pid; 15 if ((pid = fork()) == 0) { 16 printf("I'am child process "); 17 // do something 18 sleep(5); 19 exit(0); 20 } else if (pid > 0) { 21 // wake up until child exit 22 sleep(10); 23 printf("parent process exit "); 24 } else { 25 perror("fork"); 26 return -1; 27 } 28 return 0; 29 }