1. 为什么会有孤儿进程组的概念,APUE没直接写,但是GNU有规定

孤儿进程组不可以获得终端,这是为了保证控制进程死掉后他的终端可以安全分配给新session。posix要求向新孤儿进程组中停止状态的进程(GNU说是给孤儿进程组里所有进程发消息,而APUE中文版说是给停止状态的进程发消息)发送SIGHUP(挂起)信号和SIGCONT(继续)信号。首先处理SIGHUP信号,系统默认处理是终止进程,然而也可以另行处理这样进程会继续执行,但任不可以再获得终端。

2. 书本代码示例apue.3e/relation/orphan3.c较费解

#include "apue.h"
#include <errno.h> static void
sig_hup(int signo)
{
printf("SIGHUP received, pid = %ld\n", (long)getpid());
} static void
pr_ids(char *name)
{
printf("%s: pid = %ld, ppid = %ld, pgrp = %ld, tpgrp = %ld\n",
name, (long)getpid(), (long)getppid(), (long)getpgrp(),
(long)tcgetpgrp(STDIN_FILENO));
fflush(stdout);
} int
main(void)
{
char c;
pid_t pid; pr_ids("parent");
if ((pid = fork()) < ) {
err_sys("fork error");
} else if (pid > ) { /* parent */
sleep(); /* sleep to let child stop itself */
} else { /* child */
pr_ids("child");
signal(SIGHUP, sig_hup); /* establish signal handler */
kill(getpid(), SIGTSTP); /* stop ourself */
pr_ids("child"); /* prints only if we're continued */
if (read(STDIN_FILENO, &c, ) != )
printf("read error %d on controlling TTY\n", errno);
}
exit();
}

上面代码,father等待5秒后狗带,child运行结果如下:

[karenyin@host relation]$ ./orphan3
parent: pid = , ppid = , pgrp = , tpgrp = 15877 // father是组长,也是前台进程组ID,father的father是shell,shell pid=15811
child: pid = , ppid = , pgrp = , tpgrp = 15877 // child是组员,当前这个进程组占据了终端。结果输出在这里停了几秒,然后才打印下一句“SIGHUP received”
[karenyin@host relation]$ SIGHUP received, pid = 15878 // 进程组先退出终端,然后又在终端打印SIGHUP
child: pid = , ppid = , pgrp = , tpgrp = 15811 // 前台进程组已经不是father了,说明终端又交给了shell
read error on controlling TTY           // child试图读标准输入read(STDIN_FILENO, &c, 1),触发了异常。
^C                                     // child没有走到exit(0)

原因分析如下:

1. kill(15878, SIGTSTP)并不是要child杀死自己,而是暂停前台作业。

2. father自然死亡后,child成为孤儿进程,被init收养,因此ppid=1。

 child也成为进程组15877也成为孤儿进程组,因此收到SIGHUP信号(之后还会收到SIGCONT信号,表示继续)。

3. 子进程处理SIGHUP信号的时候,已经是孤儿进程组成员了,没有权限刷到标准输出,为什么成功打印了“SIGHUP received, pid = 15878”呢?同样的疑惑,为什么child能在终端打印“read error %d on controlling TTY\n”呢?关于这个疑问其实apue也有写,POSIX.1只对读控制终端作出限制。

所以说,gnu对孤儿进程组的定义里access一词的意思是“读”,孤儿进程组成员试图读取控制终端时才抛EIO,对写终端未做规定。

小结

这个故事说明,像W.Richard Stevens这种咖位的技术书籍作者,写书不会含糊其辞的。看书的时候不要自信跳过,不然有可能浪费时间。

apue第九章之孤儿进程组的更多相关文章

  1. 第九章 广播和本地组播(IGMP和MLD)

    距离项目开启已经过去了一段时间,这段时间内自己学习的内容也算挺多的,但是也较容易遗忘,之后应该在空余的时间内多翻翻博客,更加清楚传统计算机网络的运作. 由于51要出去玩,更要好好利用好最近的时间.完成 ...

  2. 《UNIX环境高级编程》(APUE) 笔记第九章 - 进程关系

    9 - 进程关系 GitHub 地址 1. 进程组 每个进程除了有一个 进程 ID 外,还属于一个 进程组 .进程组是一个或多个进程的 集合 ,通常,它们是在同一作业中结合起来的,同一进程组中的各进程 ...

  3. 进程组与会话 Linux Process Groups and Sessions

    在类Unix系统中,用户通常会跟各种相关的进程打交道.虽然在登录的时候只有一个终端进程(用户对应的登录shell ,通过这个shell启动各种程序和服务),但通常不久以后就会产生许多相关的进程,例如进 ...

  4. apue学习笔记(第九章 进程关系)

    本章将详细地说明进程组以及POSIX.1引入的会话的概念.还将介绍登录shell和所有从登录shell启动的进程之间的关系 终端登录 BSD终端登录.系统管理者创建通常名为/etc/ttys的文件,其 ...

  5. APUE 2 - 进程组(process group) 会话(session) job

    进程组(process group) 进程组顾名思义是指一个或多个进程的集合.他们通常与同一个job(可以从同一个终端接收信号)相关联.每个进程组拥有一个唯一的Process Group Id.可以使 ...

  6. 【APUE】孤儿进程与僵死进程

    基本概念: 在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程.子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束. 当一个 进程 ...

  7. 重读APUE(8)-进程、进程组、会话

    进程: 是系统中一段程序执行的实体,也是资源分配和调度的基本单位: 进程组: 为了方便管理多个进程,可以将多个进程加入到一个进程组内: 每个进程都属于一个进程组,但是同一个进程组内可以有多个进程: 每 ...

  8. Laxcus大数据管理系统2.0(11)- 第九章 容错

    第九章 容错 在当前,由于集群庞大的组织体系和复杂性,以及用户普遍要求低成本硬件,使得集群在运行过程中发生的错误概率,远远高于单一且性能稳定的小型机服务器,并且集群在运行过程中几乎是不允许停止的,这就 ...

  9. wait、waitpid 僵尸进程 孤儿进程

    man wait: NAME wait, waitpid, waitid - wait for process to change state SYNOPSIS #include <sys/ty ...

随机推荐

  1. 多管齐下显神威-2017逐浪CMS开启全新建站与WEB技术革命

    培训班里说百遍,不如商业场景来检验. PS.AI.JS工具齐上阵,一统逐浪CMS全网中间件. 从逐浪软件创业团队成立.到逐浪CMS产品,以企业形式运营,历经十二载风雨,作为华文世界排名第一的dotNE ...

  2. Python 汉诺塔

    在汉诺塔游戏中,有三个分别命名为A.B.C得塔座,几个大小各不相同,从小到大一次编号得圆盘,每个原盘中间有一个小孔.最初,所有得圆盘都在A塔座上,其中最大得圆盘在最下面,然后是第二大,以此类推. 游戏 ...

  3. win10刻录光盘失败,一直显示有准备好写入到光盘中的文件

    这是因为前面刻录留下的缓存导致的 解决方法是,删除系统刻录缓存文件 刻录缓存路径大概在以下位置(其中ase那个地方需要修改,改成自己的登录用户账号名即可) C:\Users\ase\AppData\L ...

  4. Open Distro for Elasticsearch – How Different Is It?

    转自:https://logz.io/blog/open-distro-for-elasticsearch Last month, AWS announced an initiative called ...

  5. Django学习笔记之视图高级-类视图

    类视图 在写视图的时候,Django除了使用函数作为视图,也可以使用类作为视图.使用类视图可以使用类的一些特性,比如继承等. View django.views.generic.base.View是主 ...

  6. Java ConcurrentHashMap存入引用对象时也是线程安全的

    本人小白,看到资料说ConcurrentHashMap是线程安全的,get过程不需要加锁,put是线程安全的,推荐高并发时使用.但是本人不清楚是否该map中存入的引用类型对象,对象属性变化也是否线程安 ...

  7. linux系统服务详解

    下面现介绍一下运行次序和运行级别: 一个 Linux 系统的引导过程可以分为几个阶段.我们主要看看当内核加载后的那一个阶段.你可以运行runlevel 命令来确定您的系统当前的运行级,当内核被加载并开 ...

  8. Charles断点调试

  9. jquery对append进的元素的监听操作

    通常append是再页面加载完之后才加入进去的,此时使用click方法是没有效果的,应使用document.on来实现对元素的监听. 例: $(document).on("click&quo ...

  10. 承接教育类html5交互课件/动画/游戏外包——如何快速开发一款html5交互课件/动画产品

    根据不同的课件类型选择不同的引擎,选择最合适的开发工具为您实现想要的课件效果.