UNIX(编程-进程处理):30---僵死进程、孤儿进程(SIGCLD、SIGHCLD信号处理)

一、孤儿进程

  • 父进程在子进程结束之前终止,那么子进程就变为孤儿进程
  • 对于其父进程已经终止的所有孤儿进程,它们的父进程都改变为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信号处理)

  • 虽然我们可以在父进程中调用wait、waitpid来等待子进程的结束,但是wait、waitpid的调用可能会影响父进程原本想要进行的工作,因此为了提高程序的效率,我们可以借助SIGCLD/SIGCHLD信号来处理子进程:在父进程中捕获SIGCLD/SIGHCLD信号,并在信号处理函数中调用wait/waitpid函数来“彻底结束”一个子进程
  • SIGCLD、SIGHCLD信号处理的详细介绍可以参见文章:https://blog.csdn.net/qq_41453285/article/details/89217003
  • 下面是SIGCLD信号处理的伪代码
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)
    {
        /*对结束的子进程进行善后处理*/
    }
}
发布了1300 篇原创文章 · 获赞 828 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/qq_41453285/article/details/103738733