1、概述
以下三种类型的IPC合称为System V IPC:
-
System V消息队列;
-
System V信号量;
-
System V共享内存区。
图3-1汇总了所有System V IPC函数。
2、key_t 键和 ftok 函数
三种类型的System V IPC使用 key_t 值作为它们的名字。头文件<sys/types.h>把key_t这个数据类型定义为一个整数,它通常是一个至少32位的整数。这些整数值通常是由ftok函数赋予的。
函数 ftok 把一个已存在的路径名和一个整数标识符转换成一个 key_t 值,称为IPC键。
#include <sys/ipc.h>
key_t ftok(const char *pathname, int id);
// 返回:若成功则为IPC键,若出错则为-1
该函数把从pathname导出的信息与id的低序8位组合成一个整数IPC键。
3、ipc_perm 结构
内核给每个IPC对象维护一个信息结构,其内容跟内核给文件维护的信息类似。
struct ipc_perm {
uid_t uid; /* owner's user id */
gid_t gid; /* owner's group id */
uid_t cuid; /* creator's user id */
gid_t cgid; /* creator's group id */
mode_t mode; /* read-write permissions */
ulong_t seq; /* slot usage sequence number */
key_t key; /* IPC key */
};
3、创建与打开IPC通道
创建或打开一个IPC对象的三个getxX函数(见图3-1)的第一个参数key是类型为key_t的IPC键,返回值identifier是一个整数标识符。该标识符不同于ftok函数的id参数,我们不久就会看到。对于key值,应用程序有两种选择。
(1)调用ftok,给它传递pathname和id。
(2)指定key为lPC_PRIVATE,这将保证会创建一个新的、唯一的IPC对象。
图3-3展示有关步骤的顺序。
4、 IPC权限
每当使用某个getXXX函数(指定IPC_CREAT标志)创建一个新的IPC对象时,以下信息就保存到该对象的ipc_perm结构中。
(1) oflag参数中某些位初始化 ipc_perm 结构的mode成员。图3-6展示了System V三种不同IPC机制的权限位(记号>x3的意思是将值右移3位)。
5、小结
msgget、semget和shmget这三个函数的第一个参数是一个System VIPC键。这些键通常是使用系统的ftok函数从某个路径名创建出的。键还可以是IPC_PRIVATE这个特殊值。这三个函数创建一个新的IPC对象或打开一个已存在的IPC对象,并返回一个System V IPC标识符:接下去用于给其余IPC函数标识该对象的一个整数。这些整数不是特定于进程的标识符(像描述符那样),而是系统范围的标识符。这些标识符还由内核在一段时间后重用。
与每个System VIPC对象相关联的是一个ipc_perm结构,它含有诸如属主的用户ID、组ID读写权限等信息。Posix IPC和System VIPC的差别之一是,这些信息对于System VIPC对象总是可用的(通过以IPC_STAT命令参数调用三个ct1XXX函数中的某一个),但是对于Posix IPC对象来说,能否访问这些信息要看具体实现。如果Posix IPC对象存放在文件系统中,而且我们知道它们在文件系统中的名字,那么使用现有的文件系统工具就能访问到与ipc_perm结构的内容相同的信息。
在创建一个新的System V IPC对象或打开一个已存在的对象时,可给getXXX函数指定两个标志(IPC_CREAT和IPC_EXCL),外加9个权限位。
毫无疑问,使用System V IPC的最大问题在于多数实现在这些对象的大小上施加了人为的内核限制,这些限制可追溯到它们历史上的最初实现。这就是说,较多使用System V IPC的多数应用需要系统管理员修改这些内核限制,然而不同风格的Unix完成这些修改工作的步骤也不一样。