Chinaunix首页 | 论坛 | 博客
  • 博客访问: 33988
  • 博文数量: 14
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 165
  • 用 户 组: 普通用户
  • 注册时间: 2022-11-22 23:41
个人简介

将分享技术博文作为一种快乐,提升自己帮助他人

文章分类

全部博文(14)

文章存档

2023年(9)

2022年(5)

我的朋友

分类: LINUX

2023-03-28 23:23:53

一、IPC key键值和ftok函数


唯一非零的IPC key键值一般用于system V IPC中的消息队列、信号量和共享内存中通过创建或打开IPC函数(msgget, semget或者shmget)产生对应的IPC对象标识符。而ftok()函数则是产生该IPC key键值的方式。ftok()通过一个路径名和整数标识符生成一个IPC key键值的,函数原型如下:

点击(此处)折叠或打开

  1. #include <sys/types.h>
  2. #include <sys/ipc.h>

  3. key_t ftok(const char *pathname, int proj_id);
函数入参:

pathname: 制定的文件,此文件必须存在且可访问
proj_id: 计划代号,尽管是int型,但只有低8bit才会用于生成IPC key键值(因此低8bit不可为0)。

返回值:

成功:返回key_t类型的键值,失败返回-1,错误原因存于error中。
ps: key_t一般为32位的int型类型数据。


二、ftok函数实现验证


ftok()典型实现是调用stat函数,然后组合以下三个值:
① pathname所在的文件系统的信息(stat结构的st_dev成员)。
② 该文件在本文件系统内的索引节点号(stat结构的st_ino成员)。
③ proj_id的低序8位(不能为0)。
组合产生一个32位键。 验证代码如下:

点击(此处)折叠或打开

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <sys/ipc.h>
  4. #include <sys/stat.h>

  5. int main(int argc, char **argv)
  6. {
  7.         struct stat st;

  8.         if (argc != 2) {
  9.             printf("usage: ftok \n");
  10.             exit(1);
  11.         }

  12.         stat(argv[1], &st);
  13.         printf("st_dev:%lx, st_ino:%lx, key:%x\n", st.st_dev, st.st_ino, ftok(argv[1], 0x579));
  14.         printf("st_dev:%lx, st_ino:%lx, key:%x\n", st.st_dev, st.st_ino, ftok(argv[1], 0x118));

  15.         return 0;
  16. }
编译以上代码gcc ftok_test.c -o ftok,并以一个以存在的目录运行该程序,结果如下:

点击(此处)折叠或打开

  1. st_dev:2c, st_ino:6d82, key:792c6d82
  2. st_dev:2c, st_ino:6d82, key:182c6d82

从上面程序可以看出,通过ftok返回的是根据文件(pathname)信息和工程编号(proj_id)合成的IPC key键值,从而避免用户使用key值的冲突。proj_id值的意义让一个文件也能生成多个IPC key键值。ftok利用同一文件可得到256个IPC key键值,因为ftok只取proj_id值二进制的后8位,即16进制的后两位与文件信息合成IPC key键值。


三、IPC key值选择与使用


1、key值的选择方式

对于key值,应用程序有如下三种选择:
(1) 调用ftok函数,给它传递pathname和proj_id,操作系统根据两者合成key值。
(3) 指定key为大于0的常数,这需要用户自行保证生成的IPC key值不与系统中的存在冲突,而前两种操作系统会保证。

(2) 指定key为IPC_PRIVATE,内核保证创建一个新的、唯一的IPC对象、IPC标识符与内存中的标识符不会冲突。IPC_PRIVATE为宏定义,其值等于0。

2、IPC对象标识符创建与使用

system V IPC中的消息队列、信号量和共享内存的IPC函数如下。

接口类型 消息队列 信号量 共享内存
创建或打开IPC函数 msgget semget shmget
控制IPC操作函数 msgctl semctl
shmctl
IPC操作函数
msgsnd
msgrcv
semop
shmat
shmdt

IPC标识符不同与IPC key值,如前面所述,IPC标识符是消息队列、信号量和共享内存通过创建或打开IPC函数msgget(), semget()或者shmget()函数通过key值得到的。

IPC对象标识符创建注意事项
每个IPC对象创建时都会传入flag标志参数,如msgget中为msgflg、semget中为semflg、shmget中shmflg。该flag标识是int类型,低9bit指定了所有者、所属组和其他人,这与open()函数的mode参数的格式和含义是一致的。
(1) 若创建时flag只指定所属权限组,则打开一个IPC对象标识符时,如果标识符不存在则返回失败且erron为ENOENT;若标识符存在,则返回成功,引用已存在对象。
(2) IPC的flag参数,还有以下两个标志位:

点击(此处)折叠或打开

  1. #define IPC_CREAT 01000 /* Create key if key does not exist. */
  2. #define IPC_EXCL 02000 /* Fail if key exists. */
从以上两个宏的注释也可以看出,增加了两个特殊属性。将他们加到flag的参数中,作用效果如下表所示:
flag创建模式标志 IPC对象不存在 IPC对象已存在
无特殊标志 出错,errno=ENOENT 成功,引用已存在对象
IPC_CREAT 成功,创建新对象 成功,引用已存在对象
IPC_CREAT | IPC_EXCL
成功,创建新对象
出错,errno=EEXIT

控制IPC操作函数和IPC操作函数的{BANNED}中国第一个入参都是IPC标识符,他们均是通过操作IPC对象标识符来实现进程间通信的。IPC key值和IPC标识符的使用关系如下图所示:


IPC键值与IPC标识符的使用

阅读(1335) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~