apue学习笔记(第九章 进程关系)
本章将详细地说明进程组以及POSIX.1引入的会话的概念。还将介绍登录shell和所有从登录shell启动的进程之间的关系
终端登录
BSD终端登录。系统管理者创建通常名为/etc/ttys的文件,其中每个终端设备都有一行,用来说明设备名和传到getty程序的参数。
当系统自举时,内核创建进程ID为1的进程(init进程)。init进程读取文件/etc/ttys,对每一个允许登录的终端设备调用一次fork,它所生成的子进程则exec getty程序,如下图所示:

getty对终端设备调用open函数,以读、写方式将终端打开。一旦设备被打开,则文件描述符0、1、2就被设置到该设备。然后getty输出“login:”之类的信息,并等待用户键入用户名。
当用户键入用户名后,getty的工作就完成了。然后它以类似于下列方式调用login程序:
execle("/bin/login","login","-p",username,(char *),envp);
下图显示了login刚被调用后这些进程的状态

如果用户正确登录,login就将完成如下工作:
1 将当前工作目录更改为该用户的起始目录(chdir)
2 调用chown更改该终端的所有权,是登录用户成为它的所有者
3 将该终端设备的访问权限改变成“用户读和写”
4 调用setgid及initgroups设置进程的组ID
5 用login得到的所有信息初始化环境:起始目录(HOME)、shell(SHELL)、用户名(USERNAME和LOGNAME)以及一个系统默认路径(PATH)
6 login进程更改为登录用户的用户ID(setuid)并调用该用户的登录shell,其方式类似于:execl("/bin/sh","-sh",(char *)0)
网络登录
在上节所述的终端登录中,init知道哪些终端设备科用来进行登录,并为每个设备生成一个getty进程。但是对网络登录情况则有所不同,事先并不知道将会有多少这样的登录。
BSD网络登录。作为系统启动的一部分,init调用一个shell,使其执行shell脚本/etc/rc。由此shell脚本启动一个守护进程inetd。
inetd等待TCP/IP连接请求到达主机,而当一个连接请求到达时,它执行一次fork,然后生成的子进程exec适当的程序。
TELNET是使用TCP协议的远程登录应用程序。下图显示了在执行TELNET服务进程中所涉及的进程序列

然后,telnetd进程打开一个伪终端设备,并用fork分成两个进程。父进程处理通过网络连接的通信,子进程则执行login程序。
进程组
每个进程除了有一进程ID之外,还属于一个进程组,进程组是一个或多个进程的集合,每个进程组有一个唯一的进程组ID。
可以使用getpgrp返回调用进程的进程组ID
#include <unistd.h>
pid_t getpgrp(void);
每个进程组有一个组长进程。组长进程的进程组ID等于其进程ID
进程调用setpgid可以加入一个现有的进程组或者创建一个新进程组
#include <unistd.h>
int setgpid(pid_t pid,pid_t pgid);
setpgid函数将pid进程的进程组ID设置为pgid。如果这两个参数相等,则由pid指定的进程变成进程组组长。
一个进程只能为它自己或它的子进程设置进程组ID。在它的子进程调用exec后,它就不再更改该子进程的进程组ID。
会话
会话是一个或多个进程组的集合。
进程调用setsid函数建立一个新会话。
#include <unistd.h>
pid_t setsid(void);
如果调用此函数的进程不是一个进程组的组长,则此函数创建一个新会话。具体会发生以下3件事。
1 该进程变成新会话的会话首进程
2 该进程成为一个新进程组的组长进程。新进程组ID是该调用进程的进程ID
3 该进程没有控制终端
如果该调用进程已经是一个进程组的组长,则此函数返回出错。getsid函数返回会话首进程的进程组ID
#include <unistd.h>
pid_t getsid(pid_t pid); //如果pid是0,函数返回调用进程的会话首进程的进程组ID
控制终端
会话和进程组还有一些其他特性
1 一个会话可以有一个控制终端。这通常是终端设备(在终端登录情况下)或伪终端设备(在网络登录情况下)。
2 建立与控制终端连接的会话首进程被称为控制进程。
3 一个会话的几个进程组可被分成一个前台进程组以及一个或多个后台进程组。
4 如果一个会话有一个控制终端,则它有一个前台进程组,其他进程组为后台进程组。
5 无论何时键入终端的中断键(常常是Delete或Ctrl+C),都会将终端信号发送至前台进程组的所有进程。
5 无论何时键入终端的退出键(常常是Ctrl+\),都会讲退出信号发送至前台进程组的所有进程。
6 如果终端接口检测到调制解调器(或网络)已经断开,则将挂断信号发送至终端进程(会话首进程)
这些特性示于下图中

作业控制
一个作业只是几个进程的集合,通常是一个进程管道。
例如:vi main.c 在前台启动了只有一个进程组成的作业。
而下面命令(命令后面加&可以是作业在后台运行):
pr *.c | lpr &
make all &
在后台启动了两个作业。这连个后台作业调用的所有进程都在后台运行。
当启动一个后台作业时,shell赋予它一个作业标识符,并打印一个或多个进程ID。下面演示这一点:

当作业完成而且键入回车时,shell通知作业已经完成。
只有前台作业接收终端输入,如果后台作业试图读终端,则向后台作业发送一个特定信号SIGTTIN。
该信号通常会停止此后台作业,而shell则向有关用户发送这种情况的通知,然后用户就可用shell命令将此作业转为前台作业运行,于是它就可读终端。下面将演示这一点:

使用stty命令可以允许或禁止后台作业输出到控制终端

apue学习笔记(第九章 进程关系)的更多相关文章
- 《UNIX环境高级编程》(APUE) 笔记第九章 - 进程关系
9 - 进程关系 GitHub 地址 1. 进程组 每个进程除了有一个 进程 ID 外,还属于一个 进程组 .进程组是一个或多个进程的 集合 ,通常,它们是在同一作业中结合起来的,同一进程组中的各进程 ...
- 《机器学习实战》学习笔记第九章 —— 决策树之CART算法
相关博文: <机器学习实战>学习笔记第三章 —— 决策树 主要内容: 一.CART算法简介 二.分类树 三.回归树 四.构建回归树 五.回归树的剪枝 六.模型树 七.树回归与标准回归的比较 ...
- o'Reill的SVG精髓(第二版)学习笔记——第九章
第九章:文本 9.1 字符:在XML文档中,字符是指带有一个数字值的一个或多个字节,数字只与Unicode标准对应. 符号:符号(glyph)是指字符的视觉呈现.每个字符都可以用很多不同的符号来呈现. ...
- 《Python基础教程(第二版)》学习笔记 -> 第九章 魔法方法、属性和迭代器
准备工作 >>> class NewStyle(object): more_code_here >>> class OldStyle: more_code_here ...
- 《DOM Scripting》学习笔记-——第九章 CSS-DOM
本章内容: 一.style属性 二.如何检索样式信息 三.如何改变样式 属性: 包含位置信息:parentNode , nextSibling , previousSibling , childNod ...
- 学习笔记 第九章 使用CSS美化表格
第9章 使用CSS美化表格 学习重点 正确使用表格标签: 设置表格和单元格属性: 设计表格的CSS样式. 9.1 表格的基本结构 表格由行.列.单元格3部分组成,单元格时行与列交叉的部分. 在HTM ...
- 《metasploit渗透测试魔鬼训练营》学习笔记第九章--meterpreter
七.强大的meterpreter 7.1再探metasploit的攻击载荷模块 7.1.1典型的攻击载荷模块 metasploit涵盖了各大主流操作系统和平台,其中绝大部分是远程漏洞 ...
- Head First Servlets & JSP 学习笔记 第九章 —— 使用JSTL
JSTL1.1 不是JSP2.0规范的一部分!你能访问Servlet和JSP API 不意味着你能访问JSTL! 使用JSTL之前,需要将两个文件("jstl.jar" 和 &qu ...
- Linux学习笔记(第九章)
压缩概念: gzip和zcat: 先进版bzip2,bzcat bzip -d 已压缩文档名 bzip -z 需压缩文档名 bzcat 解压文档打印到屏幕 tar:打包指令 注意:压缩最好拿掉根目录 ...
随机推荐
- Spring aop报错:com.sun.proxy.$Proxyxxx cannot be cast to yyy
在使用Spring AOP时,遇到如下的错误: Exception in thread "main" java.lang.ClassCastException: com.sun.p ...
- nginx进行项目域名配置时提示Job for nginx.service failed
ps aux | grep nginx /bin/systemctl stop nginx.service /bin/systemctl start nginx.service /bin/system ...
- [bzoj 3048] [Usaco2013 Jan]Cow Lineup
[bzoj 3048] [Usaco2013 Jan]Cow Lineup Description 给你一个长度为n(1<=n<=100,000)的自然数数列,其中每一个数都小于等于10亿 ...
- 524. Longest Word in Dictionary through Deleting
Given a string and a string dictionary, find the longest string in the dictionary that can be formed ...
- Android Timer 的 schedule()方法定时循环切换图片
void java.util.Timer.schedule(TimerTask task, long delay, long period)第一个参数,是 TimerTask 类,在包:import ...
- C# .NET4.0 改为 到.NET2.0 时 TypedTableBase 报错解决方法
.NET 4.0 降版本 到.NET 2.0.不出意外,问题必然来了. 编译错误一: 错误 1 命名空间“System”中不存在类型或命名空间名称“Linq”(是缺少程序集引用吗?)解决: 删掉该引用 ...
- windows下安装oracle,sqlplus连接启动oracle(oracle 主机字符串输入是什么)
1.oracle安装 参考http://wenku.baidu.com/view/d01ffd43336c1eb91a375d68.html,这里不再赘述 2.命令行sqlplus连接oracle ...
- es6 解构写法:给变量取别名
在变量后面加一个: var {f: foo} = {f: 5}; foo == 5 // true
- Codeforces 899 B.Months and Years
B. Months and Years time limit per test 1 second memory limit per test 256 megabytes input standar ...
- (3)Django 配置
一.settings django安装的应用程序 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.c ...