一、孤儿进程
- 父进程在子进程结束之前终止,那么子进程就变为孤儿进程
- 对于其父进程已经终止的所有孤儿进程,它们的父进程都改变为init进程。我们称这些进程由init进程领养。其操作过程大致是:在一个进程终止时,内核逐个检查所有活动进程,以判断它是否是正要终止的进程的子进程,如果是,则该进程的父进程ID就更改为1( init进程的ID)。这种处理方法保证了每个进程有一个父进程
- 一个由init进程领养的孤儿进程终止时会发生什么 ?它会不会变成一个僵死进程?
- 答案是“否”。因为init被编写成只要有一个子进程终止,init就会调用一个wait函数取得其终止状态。因此僵死进程就会被init清除。这样也就防止了在系统中有很多僵死进程
- 当提及“一个init的子进程”时,这指的是init直接产生的进程,或者是其父进程已终止,由init领养的进程
二、僵死进程
- 一个已经终止、但是其父进程尚未对其进行善后处理(获取终止子进程的有关信息、释放它仍占用的资源)的进程被称为僵尸进程
- 设置僵死状态的目的:
- 父进程一般需要跟踪子进程的退出状态,因此,当子进程结束运行时,内核不会立即释放该进程的进程表表项(信息包括该进程的ID,终止状态、以及资源利用率等),以满足父进程后续对该子进程退出信息的查询(如果父进程还在运行的话)
- 一个进程处于僵死状态之后,如果父进程调用wait、waitpid函数来处理子进程,那么僵死状态就会消失
- wait、waitpid函数见文章:https://blog.csdn.net/qq_41453285/article/details/88992605
三、孤儿进程与僵死进程的区别
- 僵死进程与孤儿进程的概念是不一样的
- 僵死进程是子进程已经结束,父进程依然存在,但是父进程还没有对子进程进行处理。孤儿进程是父进程在子进程结束之前终止
四、僵死进程的处理(SIGCLD、SIGHCLD信号处理)
void static void handle_child(int sig);
int main()
{
/*...*/
signal(SIGCLD,handle_child); //为SIGCLD信号绑定信号处理函数
/*...*/
}
void static void handle_child(int sig)
{
pid_t pid;
int stat;
while((pid=waitpid(-1,&stat,WNOHANG))>0)
{
/*对结束的子进程进行善后处理*/
}
}