apue:进程关系

来源:互联网 发布:c语言控制鼠标点击 编辑:程序博客网 时间:2024/05/01 09:50

进程组

    每个进程除了有一进程ID之外,还属于一个进程组,进程组是一个或多个进程的集合。每个进程组有一个唯一的进程组ID。进程组ID类似于进程ID——它是一个正整数,并可存放在pid_t数据类型中。函数getpgrp返回调用进程的进程。

#include <sys/types.h>#include <unistd.h>pid_t getpgrp(void);/*返回:调用进程的进程组ID*/

    每个进程组有一个组长进程。组长进程的标识是,其进程组ID等于其进程ID。进程组组长可以创建一个进程组,创建该组中的进程,然后终止。只要在某个进程组中有一个进程存在,则该进程组就存在,这与其组长进程是否终止无关。从进程组创建开始到其中最后一个进程离开为止的时间区间称为进程组的生命期。某个进程组中的最后一个进程可以终止,也可以参加另一个进程组。进程调用setpgid可以参加一个现存的组或者创建一个新进程组。

#include <sys/types.h>#include <unistd.h>int setpgid(pid_t pid, pid_t pgid);/*返回:若成功则为0,出错为-1*/

    这将pid进程的进程组ID设置为pgid。如果这两个参数相等,则由pid指定的进程变成进程组组长。一个进程只能为它自己或它的子进程设置进程组ID。在它的子进程调用了exec后,它就不再能改变该子进程的进程组ID。如果pid是0,则使用调用者的进程ID。另外,如果pgid是0,则由pid指定的进程ID被用作为进程组ID。

对话期

    对话期(session)是一个或多个进程组的集合。进程组和对话期的进程安排如下图所示:
进程组和对话期的进程安排
    进程调用setsid函数就可建立一个新对话期。

#include <sys/types.h>#include <unistd.h>pid_t setsid(void);/*返回:若成功则为进程组ID,若出错则为-1*/

    如果调用此函数的进程不是一个进程组的组长,则此函数创建一个新对话期,结果为:
- 此进程变成该新对话期的对话期首进程(session leader,对话期首进程是创建该对话期的进程)。此进程是该新对话期中的唯一进程。
- 此进程成为一个新进程组的组长进程。新进程组ID是此调用进程的进程ID。
- 此进程没有控制终端。如果在调用setsid之前此进程有一个控制终端,那么这种联系也被解除。
    如果此调用进程已经是一个进程组的组长,则此函数返回出错。

控制终端

    对话期和进程组有一些其他特性:
- 一个对话期可以有一个单独的控制终端(controlling terminal)。这通常是我们在其上登录的终端设备(终端登录情况)或伪终端设备(网络登录情况)。
- 建立与控制终端连接的对话期首进程,被称之为控制进程(controlling process)。
- 一个对话期中的几个进程组可被分成一个前台进程组(foreground process group)以及一个或几个后台进程组(background process group)。
- 如果一个对话期有一个控制终端,则它有一个前台进程组,其他进程组则为后台进程组。
- 无论何时键入中断键(常常是DELETE或Ctrl-C)或退出键(常常是Ctrl-\),就会造成将中断信号或退出信号送至前台进程组的所有进程。
- 如果终端界面检测到调制解调器已经脱开连接,则将挂断信号送至控制进程(对话期首进程。)
    这些特性如下图所示。
对话期和进程组关系

tcgetpgrp和tcsetpgrp函数

    需要有一种方法来通知内核哪一个进程组是前台进程组,这样,终端设备驱动程序就能了解将终端输入和终端产生的信号送到何处。

#include <sys/types.h>#include <unistd.h>pid_t tcgetpgrp(int filedes);/*返回:若成功则为前台进程组ID,若出错则为-1*/int tcsetpgrp(int filedes, pid_t pgrpid);/*返回:若成功则为0,若出错则为-1*/

    函数tcgetpgrp返回前台进程组ID,它与在filedes上打开的终端相关。如果进程有一个控制终端,则该进程可以调用tcsetpgrp将前台进程组ID设置为pgrpid。pgrpid值应当是在同一对话期中的一个进程组的ID。filedes必须引用该对话期的控制终端。

作业控制

    作业控制允许在一个终端上起动多个作业(进程组),控制哪一个作业可以存取该终端,以及哪些作业在后台运行。作业控制要求三种形式的支持:
- 支持作业控制的shell。
- 内核中的终端驱动程序必须支持作业控制。
- 必须提供对某些作业控制信号的支持。
    从shell使用作业控制功能角度观察,可以在前台或后台起动一个作业。一个作业只是几个进程的集合,通常是一个进程管道。
    有三个特殊字符可使终端驱动程序产生信号,并将它们送至前台进程组,它们是:
- 中断字符(一般采用DELETE或Ctrl-C)产生SIGINT。
- 退出字符(一般采用Ctrl-\)产生SIGQUIT。
- 挂起字符(一般采用Ctrl-Z)产生SIGTSTP。

孤儿进程组

    一个父进程已终止的进程称为孤儿进程(orphan process),这种进程由init进程收养。

0 0
原创粉丝点击