
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
进程是大多数人在学习Java编程开发语言的时候需要重点掌握的一个编程知识点,今天我们就通过案例分析来简单了解一下,孤儿进程组和终端的关系。
在前面我们提到了当一个进程的父进程退出之后,这个进程就会变成一个孤儿进程,其实与孤儿进程对应的有一个孤儿进程组,所谓孤儿进程组就是:一个进程组当中的进程要么是孤儿进程,要么父进程也在这个进程组当中,要么父进程在其他的会话当中,满足上述条件的进程组就是孤儿进程组。
事实上内核在一种情况下也会发送SIGHUP信号给孤儿进程组,这个情况如下:
父进程程序执行完成退出了,但是子进程还没有结束,而且被挂起了。
当父进程退出的时候,shell会在他内部维护的作业列表(joblist)将退出的作业删除掉。子进程被init进程收养变成了孤儿进程,根据上文当中提到了孤儿进程组的概念,这是一个孤儿进程组,因为这个进程组当中的所有进程(如果不是多进程程序,只有一个)的父进程要么退出,要么父进程也在这个进程组当中,要么父进程在其他的会话当中。条件已经满足,因此这个进程组是一个孤儿进程组。
现在有一个问题是,这个被挂起的孤儿进程没有谁去唤醒啊,理论上来说,在父进程退出之前,子进程被挂起,应该是父进程去收拾好这个烂摊子,但是现在父进程退出了,被挂起的孤儿进程没有在运行,那么就一直会占着他对应的系统资源,如果这样的进程过多的话,那么系统的资源将会被消耗殆尽。
因此为了解决这种问题:如果一个进程组变成了孤儿进程组并且拥有已停止执行的成员,比如说被挂起来的进程,那么内核会向进程组中的所有成员发送一个SIGHUP信号通知它们已经与会话断开连接了,之后再发送一个SIGCONT信号确保它们恢复执行。如果孤儿进程组不包含被停止的成员,那么就不会发送任何信号。
孤儿进程组和终端的读和写
在前面的文章当中我们已经谈到了,当后台进程试图从控制终端中调用read()时将会收到SIGTTIN信号,当后台进程试图向设置了TOSTOP标记的控制终端调用write()时会收到SIGTTOU信号。但向一个孤儿进程组发送这些信号毫无意义,因为一旦被停止之后,它将再也无法恢复了。基于此,在进行read()和write()调用时内核会返回EIO的错误,而不是发送SIGTTIN或SIGTTOU信号。基于类似的原因,如果SIGTSTP、SIGTTIN以及SIGTTOU信号的分送会导致停止孤儿进程组中的成员,那么这个信号会被毫无征兆地丢弃。这种行为不会因为信号发送方式(如信号可能是由内核产生的或由显式地调用kill()而发送)的改变而改变。
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。更多内容请加抖音达内三江区域学习了解。