僵尸进程的产生及处理
1. 僵尸进程的产生:
子进程先于父进程结束,父进程没有获取子进程的退出码,此时子进程变成僵尸进程。
代码见进程,这里面的子进程先结束(n=2 输出两遍,就结束了),运行结果见下图,ps -aux 查看到的子进程,在n=2 输出两次之后就出现了僵尸进程
2. 僵尸进程的处理
a. 父进程调用wait()方法获取子进程的进程码
b. 父进程先结束,会出现孤儿进程,孤儿进程会被init进程接收
wait 函数的使用 可以用man 2 wait查看
#include <sys/types.h> #include <sys/wait.h> pid_t wait(int *wstatus);
函数功能是:
父进程一旦调用了wait就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果子进程结束,获取进程码,由操作系统将此子进程销毁;
如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。
*wstatus参数是一个整型指针,用于存放子进程的终止状态,也可以定义为空指针。
在父进程调用 wait 函数之后,会出现下面三种情况:
- 如果父进程的所有子进程都在运行,则父进程处于阻塞
- 如果父进程的子进程,有一个子进程已经结束了,则父进程获取该子进程的终止状态,并立即返回
- 如果父进程没有任何子进程,则立即出错返回
fork_process.c 代码添加 wait 函数,代码如下:
[root@localhost linux]# cat fork_process.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/wait.h> int main () { char * process_name = NULL; int n, i; pid_t id = fork(); if (id == 0) { process_name = "child "; printf("fork->child id=%d\n",id); n = 2; } else { process_name = "parent "; printf("fork->parent id=%d\n",id); n = 5; int val = 0; wait(&val); // 此处也可以用wait(NULL); } for ( i = 0; i < n; i++) { printf("process=%s pid=%d ppid=%d n=%d \n", process_name,getpid(),getppid(),n); sleep(2); } }
运行结果如图: