定义.
1.孤儿进程,就是父进程先于子进程退出,子进程会被挂到init进程(1号进程)下作为init的子进程,init进程对其进行管理。
2.僵死进程,就是子进程退出了,但是父进程没有对它进行善后处理,一个进程退出,操作系统会释放其打开的文件,所占用的内存,但是会留下一些信息比如退出状态,运行时间,并且占用了分配给他的进程ID。
危害.
看着这2种进程的名字貌似就不太健康,那么都有些什么危害呢?孤儿进程其实并没什么危害,因为init进程接管了它,就算它退出,那些未释放的资源也被init处理了,但是僵死进程却不同,设想如果一个父进程不断产生僵死进程,到一定的数量时,系统的pid被占用完了。
如何避免.
首先对于孤儿进程不需要管它,僵死进程就需要释放它占用的资源(退出状态,运行时间,进程ID),它们是如何被清除呢?就是使用wait或者waitpid函数来处理,其实任何一个子进程都会有短暂的僵死态,从它退出到wait或者waitpid调用返回之前,它都是处于僵死状态的。有以下2种方法避免僵死进程的出现(准确的讲是长时间处于僵死态):
1.捕捉子进程退出信号,在信号处理函数里面调用waitpid,wait
1 static void sig_child(int signal) 2 { 3 printf("receive sig "); 4 pid_t pid; 5 int stat; 6 7 while( (pid = waitpid(-1, &stat, WNOHANG)) > 0 ) 8 { 9 printf("child %d terminated. ",pid); 10 } 11 } 12 13 int main() 14 { 15 pid_t pid; 16 17 signal(SIGCHLD,sig_child); 18 pid = fork(); 19 if (pid < 0) 20 { 21 perror("fork error:"); 22 exit(1); 23 } 24 else if (pid == 0) 25 { 26 exit(0); 27 } 28 29 sleep(2); 30 system("ps -o pid,ppid,state,tty,command "); 31 return 0; 32 }
2.apu里面介绍的调用2次fork
1 int main() 2 { 3 pid_t pid; 4 5 pid = fork(); 6 if (pid < 0) 7 { 8 perror("fork error:"); 9 exit(1); 10 } 11 else if (pid == 0) 12 { 13 pid = fork(); 14 if (pid < 0) 15 { 16 perror("fork error:"); 17 exit(1); 18 } 19 else if ( pid > 0 ) 20 { 21 exit(0); //<-------------------- 22 } // 23 // 24 //this child process's parents process is init// 25 //waitpid is unnecessary // 26 sleep(2); // 27 exit(0); // 28 } // 29 // 30 if ( waitpid(pid, NULL, 0) != pid )//------------ 31 { 32 perror("waitpid"); 33 } 34 35 return 0; 36 }
其实都是等于调用wait,waitpid