一. fork()函数及僵尸进程
- 僵尸进程有啥坏处?
占用进程号,如果进程号都被占用完了,系统将不能创建新的进程。另外也会占用系统资源。
- 如何产生僵尸进程?
即:主进程调用fork()---->子进程结束--->主进程未调用wait/waitpid来得到子进程的退出信息--->子进程就会沦为僵尸进程。比如下面的例子
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> int main() { pid_t pid; pid = fork(); if(pid < 0) { printf("error occurred!\n"); } else if(pid == 0) { exit(0); } else { sleep(300); /* 获取僵尸进程的退出信息 */ wait(NULL); } return 0; }
在子进程结束后,子进程沦为僵尸进程,直到300s后主进程调用wait才为子进程收尸。
- 清除僵尸进程有以下两种方法:
1、父进程调用wait函数,为子进程“收尸”。
2、父进程不调用wait退出,init进程会变为子进程的父进程,init进程会为子进程“收尸”。
- 通过fork()两次避免产生僵尸进程
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<sys/types.h> int main() { pid_t id1=fork(); if(id1==0)//child { pid_t id2=fork(); //避免僵尸进程 if(id2>0) //father 直接退出 { exit(0); } else { sleep(2); //保证他的父进程先执行 printf("second child de father id=%d\n",getppid()); //他会成为孤儿进程,1号进程将会收养他 exit(0); } } else //father { waitpid(id1,NULL,0); //立即来等待子进程结束 } return 0; }
- 原理:让儿子进程结束掉,让init进程收养孙子进程,从而父进程不用调用wait去为孙子进程收尸。