APUE------进程关系

来源:互联网 发布:淘宝御泥坊官网 编辑:程序博客网 时间:2024/05/21 21:48

进程组

每个进程除了有一进程ID之外,还属于一个进程组。

进程组是一个或多个进程的集合。通常他们是在同一个作业中结合起来的,同意进程组中的各进程接受来自同一终端的各种信号。每个进程组有一个唯一的进程组ID。
函数getpgrp返回调用进程的进程组ID

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

返回改进程的进程组ID

#include <unistd.h>pid_t getpgid(pid_t pid);//返回值:若成功,返回进程组ID;若出错,返回-1

每一个进程组有一个组长进程。组长进程的进程组ID等于其进程ID。
进程组组长可以创建一个进程组、创建该组中的进程,然后终止。只要在某个进程组中有一个进程存在,则该进程组就存在,这与其组长进程是否终止无关。从进程组创建开始到其中最后一个进程离开为止的时间区间称为进程组的生命期。某个进程组中的最后一个进程可以终止,也可以转移到另一个进程组。

调用setpgid可以加入一个现有的进程组或者创建一个新进程组。

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

如果两个参数相等,则pid指定的进程变成进程组组长。如果pid是0,则使用调用者的进程ID。如果pgid是0,则由pid指定的进程ID用作进程组ID。

一个进程只能为自己或子进程设置进程组ID。在它的子进程调用了exec后,它就不再更改该子进程的进程组ID。

会话

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

通常是由shell的管道将几个进程编成一组的。

进程调用setsid函数建立一个新会话。

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

如果调用此函数的进程不是一个进程组的组长,则此函数创建一个新会话。具体会发生以下3件事
1. 该进程变成新会话的会话首进程。此时,该进程是新会话中的唯一进程。
2. 该进程成为一个新进程组的组长进程。新进程组ID是该调用进程的进程ID
3. 该进程没有控制终端。如果在调用setsid之前该进程有一个控制终端,那么这种联系也被切断。

如果该调用进程已经是一个进程组的组长,则此函数返回出错。为了保证不处于这种情况,通常先调用fork,然后使其父进程终止,而子进程则继续。因为子进程继承了父进程组ID,而其进程ID则是新分配的,两者不可能相等,这就保证了子进程不是一个进程组的组长。

getsid函数返回会话进程的进程组ID

#include <unistd.h>pid_t getsid(pid_t pid);//返回值:若成功,返回会话首进程的进程组ID;若出错,返回-1

如果pid是0,getsid返回调用进程的会话首进程的进程组ID。

控制终端

会话和进程组还有一些其他特性。
1. 一个会话可以有一个控制终端(controlling terminal)。
2. 建立与控制终端连接的会话首进程被称为控制进程。
3. 一个会话中的几个进程组可被分成一个前台进程组以及一个或多个后台进程组
4. 如果一个会话有一个控制终端,则它有一个前台进程组,其他进程组为后台进程组。
5. 无论何时键入终端的中断键,都会将终端信号发送至前台进程组的所有进程。
6. 无论何时键入终端的退出键,都会将退出信号发送至前台进程组的所有进程。
7. 如果终端接口检测到调制解调器已经断开连接,则将挂断信号发送至控制进程。

函数tcgetpgrp、tcsetpgrp和tcgetsid

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

函数tcgetpgrp返回前台进程组ID,它与在fd上打开的终端相关联。
如果进程有一个控制终端,则该进程可以调用tcsetpgrp将前台进程组ID设置为pgrpid。pgrpid值应当是在同一会话中的一个进程组的ID。fd必须引用该会话的控制终端
大多数应用程序并不直接调用这连个函数。他们通常由作业控制shell调用。

给出控制TTY的文件描述符,通过tcgetsid函数,应用程序就能获得会话首进程的进程组ID

#include <termios.h>pid_t tcgetsid(int fd);//返回值:若成功,返回会话首进程的进程组ID;若出错,返回-1

作业控制

作业控制要求一下3中形式的支持。
1. 支持作业控制的shell
2. 内核中的终端驱动程序必须支持作业控制
3. 内核必须提供对某些作业控制信号的支持

从shell使用作业控制功能的角度观察,用户可以在前台或后台启动一个作业。一个作业只是几个进程的集合,通常是一个进程管道。
例如:vi main.c
在前台启动了只有一个进程组成的作业
下面的命令:
pr  *.c | lpr &
make all &
在后台启动了两个作业。这两个后台作业调用的所有进程都在后台运行。

0 0
原创粉丝点击