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. 设计模式—模板方法(template method)

    一.定义 百度百科给的定义:定义一个操作中的算法骨架(稳定),而将一些步骤延迟到子类中(变化).Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 如何做到 ...

  2. vue列表拖拽组件 vue-dragging

    安装 $ npm install awe-dnd --save 应用 在main.js中,通过Vue.use导入插件 import VueDND from 'awe-dnd' Vue.use(VueD ...

  3. 2018-2019-2 20165313 Exp2 后门原理与实践

    实践基础问题回答 (1)例举你能想到的一个后门进入到你系统中的可能方式? 应用程序设定后门,用户安装后,后门就可以进入.例如课堂上讲到的百度. (2)例举你知道的后门如何启动起来(win及linux) ...

  4. 关于符号匹配题的一些思考过程--含cin.getline()函数的一些基本原理

    刚刚拿到题目的时候,还没啥感觉,就是觉得要用到if--else就可以了,但是一联想到现在是在学栈,那么是不是要用到栈呢? 一.那么先看看题目吧 给定一串字符,不超过100个字符,可能包括括号.数字.字 ...

  5. c#实现识别图片上的验证码数字

    这篇文章主要介绍了c#实现识别图片上的验证码数字的方法,本文给大家汇总了2种方法,有需要的小伙伴可以参考下. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 ...

  6. from组件

    目录 一.生成页面可用的 HTML标签 二.对用户提交的数据进行校验 三. form 综合示例: 四. modelform(自动根据字段生成表单) 五.modelformset 一.生成页面可用的 H ...

  7. python实现将字符串中以大写字母开头的单词前面添加“_”下划线

    在工作中写测试用例代码生成的时候,函数命令考虑采用参数文件的名称来命名,但是发现文件命名是驼峰的写写法,所以想按照字符串中的大写字母做分割,每个单词前面添加下划线,主要考虑采用正则的模式来匹配,替换然 ...

  8. Linux之正则表达式2之()、[]、{}区别

    正则表达式的() [] {} 有着不同的意思. () 是为了提取匹配字符串的,表达式中有几个()就有几个相应的匹配字符串 (\s*)表示连续空格的字符串 [] 是定义匹配的字符范围.比如[a-zA-Z ...

  9. ELK实践-Kibana定制化扩展

    纵观任何一家大数据平台的技术架构,总少不了ElasticSearch:ES作为溶合了后端存储.快速检索.OLAP分析等功能的一套开源组件,更绝的是提供了一套集数据采集与前端展现为一体的框架(即ELK) ...

  10. Ubuntu16.04下安装xunsearch+opencc实现php客户端的中文分词

    1.准备服务器环境 apt-get install apache2 php mysql-server apt-get install mysql-client phpmyadmin apt-get i ...