什么是僵尸进程
子进程退出时,父进程并未对其发出的SIGCHLD
信号进行适当处理,导致子进程停留在僵死状态等待其父进程为其收尸,这个状态下的子进程就是僵死进程。
僵尸进程将会占据系统资源,由于系统的进程ID是有限的,所以大量的僵尸进程会导致用户创建进程失败。
避免僵尸进程两种方式
一、 父进程可以马上退出,使得子进程成为孤儿进程,由系统将子进程的ppid改为1(init进程
),并由init进程
来回收子进程的资源。
实现这一要求的技巧是fork
两次。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/wait.h> int main() { pid_t pid; if((pid = fork())<0){ printf("fork err\n"); exit(0); }else if(pid == 0){ if((pid = fork())<0){ printf("fork err\n"); exit(0); }else if(pid > 0){ exit(0); } sleep(2); printf("second child,parent pid = %d\n",getppid()); exit(0); } if(waitpid(pid,NULL,0)!= pid){ printf("waitpid error\n"); exit(0); } exit(0); }
|
二、 父进程声明一个信号处理函数,得到子进程的退出信号,然后在信号处理函数调用wait函数彻底结束子进程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #include<signal.h> #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<sys/wait.h> pid_t pid; void handle_child(int sig) { if(waitpid(pid,NULL,0)!=pid){ printf("waitpid error\n"); exit(0); } printf("child exit\n"); exit(0); } int main() { (void) signal (SIGCHLD,handle_child); if((pid = fork())<0){ printf("fork error\n"); exit(0); } if(pid == 0){ sleep(2); exit(0); } while(1) { sleep(1); } }
|