第9章 进程关系

9.2 终端登陆

BSD终端登陆

clipboard.png

-------------------------------------------------Figure 1------------------------------------------------------

9.3 网络登录

clipboard.png

-------------------------------------------------Figure 2------------------------------------------------------

9.4 进程组

pid_t getpgrp(void);
int setpgid(pid_t pid, pid_t pgid);

1. 进程调用setpgid可以加入一个现有的进程组或者创建一个新进程组
2. setpgid函数将pid进程的进程组ID设置为pgid。如果这两个参数相等,则由pid指定的进程变成进程组组长
3. 一个进程只能为它自己或它的子进程设置进程组ID。在它的子进程调用exec后,它就不再更改该子进程的进程组ID

【【第三条意味着父子进程不一定处于同一个进程组】】

9.5 会话

会话是一个或多个进程组的集合

proc1 | proc2 &
proc3 | proc4 | proc5

clipboard.png

-------------------------------------------------Figure 3------------------------------------------------------
创建一个新会话的过程

pid_t setsid(void);

若调用此函数的进程不是一个进程组的组长,则此函数就会创建一个新会话,结果将发生下面3件事

1. 该进程变成新会话首进程(会话首进程是创建该会话的进程),此时该进程是新会话中的惟一进程
2. 该进程称为一个新进程组的组长进程。新进程组ID是该调用进程的进程ID
3. 该进程没有控制终端。如果在调用setsid之前该进程有一个控制终端,那么这种联系也会被中断

如该调用进程已经是一个进程组的组长,则此函数返回出错。

为了保证不发生这种情况,通常先调用fork,然后使其父进程终止,而子进程继续。
因为子进程继承了父进程的进程组ID,而其进程ID则是新分配的,两者不可能相等,所以这就保证子进程不会是一个进程组的组长。

pid_t getsid(pid_t pid);

获取会话首进程的进程组ID

9.6 控制终端

会话和进程组的特性:

1. 一个会话可以有一个控制终端。这通常是登录到其上的终端设备(在终端登录情况下)或伪终端设备(在网络登陆情况下)
2. 建立与控制终端链接的会话首进程被称为控制进程
3. 一个会话中的几个进程组可被分成一个前台进程组以及一个或几个后台进程组
4. 如果一个会话有一个控制终端,则它有一个前台进程组,会话中的其他进程组则为后台进程组
5. 无论何时键入终端的中断键,就会将中断信号发送给前台进程组的所有进程
6. 无论何时键入终端的退出键,就会将退出信号发送给前台进程组的所有进程
7. 如果终端接口检测到调制解调器已经断开连接,则将挂断信号发送给控制进程

clipboard.png

-------------------------------------------------Figure 4------------------------------------------------------

9.8 作业控制

【定义】
作业控制 允许在一个终端上启动多个作业(进程组),它控制哪一个作业可以访问该终端以及哪些作业在后台运行

实际上有三个特殊字符可使终端驱动程序产生信号,并将它们送至前台进程组,它们是:
中断字符(一般采用DELETE或Ctrl-C)产生SIGINT
退出字符(一般采用Ctrl- 反斜杠)产生SIGQUIT
挂起字符(一般采用Ctrl-Z)产生SIGTSTP

只有前台作业接收终端输入,如果后台作业试图读终端,那么这并不是一个错误,但是终端驱动程序检测这种情况,
并且发送一个特定信号SIGTTIN给后台作业, 这通常会 【【停止】】 此后台作业。

输入 : 转为前台进程的方法:

$ cat > temp.foo &                          在后台启动,但将从标准输入读
[1] 1681
$                                           键入回车
[1] + Stopped (tty input) cat > temp.foo &
$ fg %1                                     使1号作业成为前台作业
cat > temp.foo                              shell告诉我们现在哪一个作业在前台
hello, world                                输入1行
^D                                          键入文件结束符
$ cat temp.foo                              检查该行已送入文件
hello, world

输出 : 转为前台进程的方法:

$ cat temp.foo &                             在后台执行
[1] 1719
$ hello, world                               在提示符后出现后台作业的输出
                                             键入回车
[1] + Done cat temp.foo &
$ stty tostop                                禁止后台作业向控制终端输出 (【stty -tostop (启用)】)
$ cat temp.foo &                             在后台再次执行
[1] 1721
$                                            键入回车,发现作业已停止
[1] + Stopped(tty output) cat temp.foo &
$ fg %1                                      将停止的作业恢复为前台作业
cat temp.foo                                 shell告诉我们现在哪一个作业在前台
hello, world                                 该作业的输出

clipboard.png

-------------------------------------------------Figure 5------------------------------------------------------

9.10 孤儿进程组

【【定义】】
该组中每个成员的父进程或者是该组的一个成员,或者不是该组所属会话的成员。
对孤儿进程组的另一种描述可以是----一个进程组不是孤儿进程组的条件是:该组中有一个进程,其父进程在属于同一对话期的另一个组中。
如果进程组不是孤儿进程组,那么在属于同一对话期的另一个组中的父进程就有机会重新起动该组中停止的进程。

clipboard.png

-------------------------------------------------Figure 5------------------------------------------------------
在a.out终止后,进程组(pgid=Z)成为孤儿进程组,POSIX.1要求向新孤儿进程组中处于停止状态的每一个进程发送挂断信号(SIGHUP),
接着又向其发送继续信号(SIGCONT).在处理了挂断信号后,子进程继续。
对挂断信号的系统默认动作是终止该进程,为此必须提供一个信号处理程序以捕捉该信号。

ADDITION 进程状态

源于这一章多次提到进程的停止状态(TASK_STOPPED):
R (TASK_RUNNING),可执行状态。
S (TASK_INTERRUPTIBLE),可中断的睡眠状态。
D (TASK_UNINTERRUPTIBLE),不可中断的睡眠状态。
T (TASK_STOPPED or TASK_TRACED),暂停状态或跟踪状态。
Z (TASK_DEAD - EXIT_ZOMBIE),退出状态,进程成为僵尸进程。

注意 S与D的区别,T和S的区别


shiyang6017
158 声望59 粉丝

引用和评论

0 条评论