临桂县住房和城乡建设局网站,永年做网站,高端顺口公司名字,wordpress模板淘宝客模板下载9.1 引言
本章详细说明进程组以及会话的概念#xff0c;还将介绍登录shell#xff08;登录时所调用的#xff09;和所有从登录shell启动的进程之间的关系。
9.2 终端登录 9.3 网络登录 9.4 进程组
每个进程除了有一进程ID之外#xff0c;还属于一个进程组#xff0c;进…9.1 引言
本章详细说明进程组以及会话的概念还将介绍登录shell登录时所调用的和所有从登录shell启动的进程之间的关系。
9.2 终端登录 9.3 网络登录 9.4 进程组
每个进程除了有一进程ID之外还属于一个进程组进程组是一个或多个进程的集合同一进程组中的各进程接收来自同一终端的各种信号每个进程组有一个唯一的进程组ID它是一个正整数。
getpgrp函数返回调用进程的进程组ID
#include unistd.hpid_t getpgrp(void);// 返回值调用进程的进程组ID getpgid函数返回指定进程的进程组ID
#include unistd.hpid_t getpgid(pid_t pid);// 返回值若成功返回进程组ID若出错返回-1若pid参数是0返回调用进程的进程组ID即getpgid(0)等效于个getpgrp()。
进程组相关概念
每个进程组有一个组长进程组长进程的进程组ID等于其进程ID进程组组长可以创建一个进程组、创建该组中的进程然后终止只要在某个进程组中有一个进程存在则该进程组就存在这与其组长进程是否终止无关从进程组创建开始到其中最后一个进程离开为止的时间区间称为进程组的生命期某个进程组中的最后一个进程可以终止也可以转移到另一个进程组。
进程调用setpgid可以加入一个现有的进程组或者创建一个新进程组
#include unistd.hint setpgid(pid_t pid, pid_t pgid);// 返回值若成功返回0若出错返回-1函数将pid进程的进程组ID设置为pgid如果两个参数相等则由pid指定的进程变成组长进程如果pid是0则使用调用者的进程ID如果pgid是0则由pid指定的进程ID用作进程组ID一个进程只能为它自己或它的子进程设置进程组ID且子进程调用了exec后它就不再更改该子进程的进程组ID。
9.5 会话
会话是一个或多个进程组的集合。 进程调用setsid函数建立一个新会话
#include unistd.hpid_t setsid(void);// 返回值若成功返回进程组ID若出错返回-1如果调用此函数的进程不是一个进程组的组长则此函数创建一个新会话具体会发生以下3件事 1该进程变成新会话的会话首进程会话首进程是创建该会话的进程此时该进程是新会话中的唯一进程可将会话首进程ID视为会话ID 2该进程成为一个新进程组的组长进程新进程组ID是该调用进程的进程ID 3该进程没有控制终端新会话没有控制终端如果在调用setsid之前该进程有一个控制终端那么这种联系也被切断。如果该调用进程已经是一个进程组的组长则此函数返回出错。
getsid函数返回会话首进程的进程组ID
#include unistd.hpid_t getsid(pid_t pid);// 返回值若成功返回会话首进程的进程组ID若出错返回-1如若pid是0getsid返回调用进程的会话首进程的进程组ID如若pid并不属于调用者所在的会话那么调用进程就不能得到该会话首进程的进程组ID。
9.6 控制终端
会话和进程组还有一些其他特性
一个会话可以有一个控制终端这通常是终端设备在终端登录情况下或伪终端设备在网络登录情况下建立与控制终端连接的会话首进程被称为控制进程一个会话中的几个进程组可被分为一个前台进程组以及一个或多个后台进程组如果一个会话有一个控制终端则它有一个前台进程组其他进程组为后台进程组无论何时键入终端的中断键常常是Delete或CtrlC都会将中断信号发送至前台进程组的所有进程无论何时键入终端的退出键常常是Ctrl\都会将退出信号发送至前台进程组的所有进程如果终端接口检测到调制解调器或网络已经断开连接则将挂断信号发送至控制进程会话首进程。
9.7 函数tcgetpgrp、tcsetpgrp和tcgetsid
需要有一种方法来通知内核哪一个进程组是前台进程组这样终端设备驱动程序就能知道将终端输入和终端产生的信号发送到何处
#include unistd.hpid_t tcgetpgrp(int fd);// 返回值若成功返回前台进程组ID若出错返回-1
int tcsetpgrp(int fd, pid_t pgrpid);// 返回值若成功返回0若出错返回-1函数tcgetpgrp返回前台进程组ID它与在fd上打开的终端相关联如果进程有一个控制终端则该进程可以调用tcsetpgrp将前台进程组ID设置为pgrpidpgrpid值应当是在同一会话中的一个进程组的IDfd必须引用该会话的控制终端。
给出控制TTY的文件描述符通过tcgetsid函数应用程序就能获得会话首进程的进程组ID
#include termios.hpid_t tcgetsid(int fd);// 返回值若成功返回会话首进程的进程组ID若出错返回-19.8 作业控制
3个特殊字符可使终端驱动程序产生信号并将它们发送至前台进程组
中断字符一般采用Delete或CtrlC产生SIGINT退出字符一般采用Ctrl\产生SIGQUIT挂起字符一般采用CtrlZ产生SIGTSTP。 9.9 shell执行程序
shell处理管道的方式
shell fork一个它自身的副本然后此副本再为管道中的每条命令各fork一个进程管道中的最后一个进程是shell的子进程而执行管道中其他命令的进程则是该最后进程的子进程。 9.10 孤儿进程组
一个其父进程已终止的进程称为孤儿进程这种进程由init进程“收养”整个进程组也可成为“孤儿”孤儿进程组定义为该组中每个成员的父进程要么是该组的一个成员要么不是该组所属会话的成员。孤儿进程组的另一种描述一个进程组不是孤儿进程组的条件是——该组中有一个进程其父进程在属于同一会话的另一个组中。如果进程组不是孤儿进程组那么在属于同一会话的另一个组中的父进程就有机会重新启动该组中停止的进程。
若父进程是由shell作为前台作业执行的当父进程终止时子进程变成后台进程组。
9.11 FreeBSD实现 9.12 实例代码
chapter9