【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信基础

时间:2022-05-30 10:19:14


【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信基础


System V IPC基础

可以使用ipcs查看当前系统正在使用的IPC工具。可以看出,一个IPC工具至少包含key值、ID值、拥有着、权限和使用大小等关键信息。如需手动删除某个IPC机制,可以使用ipcrm命令。

任何一个IPC对象,都和普通文件一样,具有创建者、创建者组、拥有着和拥有着组。

【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信基础

key值和ID值

Linux系统为每个IPC机制都分配了唯一的ID,所有针对该IPC机制的操作都使用对应的ID。因此,通信的双方都需要通过某个办法来获取ID值。显然,创建者根据创建函数的返回值可获取该值,但另一个进程如何实现呢?显然,Linux两个进程不能随意访问对方的空间(一个特殊是,子进程可以继承父亲进程的数据,实现父亲进程向子进程的单向传递),也就不能够直接获取这一ID值。
为解决这一问题,IPC在实现时约定使用key值做为参数创建,如果在创建时使用相同的key值将得到同一个IPC对象的ID(即一方创建,另一方获取的是ID),这样就保证了双方可以获取用于传递数据的IPC机制ID值。key值是一个32为的整型数据。 

ftok()用来创建key值

【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信基础

【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信基础

ftok使用示例:

#include<sys/ipc.h>
#include<stdio.h>
#include<sys/stat.h>
#include<stdlib.h>

int main(int argc,char *argv[])
{
key_t key;
int i;
struct stat buf;
if(argc!=3)
{
printf("use: command path number\n");
return 1;
}

i=atoi(argv[2]);
if((stat(argv[1],&buf))==-1)
{
perror("stat");
exit(EXIT_FAILURE);
}
printf("file st_dev=0x%x\n",buf.st_dev);
printf("file st_ino=0x%x\n",buf.st_ino);
printf("number=0x%x\n",i);
key=ftok(argv[1],i);

printf("key=0x%x \tkey>>24=%x \tkey&0xffff=%x \t(key>>16)&0xff=%x\n",key,key>>24,key&0xffff,(key>>16)&0xff);
}
运行结果:

$ ./ftok_exp ../ 4
file st_dev=0x801
file st_ino=0xe0560
number=0x4
key=0x4010560 key>>24=4 key&0xffff=560 (key>>16)&0xff=1

拥有着权限存储结构struct ipc_perm

系统使用ipc_perm 结构来保存每个IPC 对象权限信息。在Linux 的库文件linux/ipc.h
中,它是这样定义的:
struct ipc_perm
{
key_t key;
ushort uid; /* owner euid and egid */
ushort gid;
ushort cuid; /* creator euid and egid */
ushort cgid;
ushort mode; /* access modes see mode flags below */
ushort seq; /* slot usage sequence number */
};
结构里的前几个成员的含义是明显的,分别是IPC 对象的关键字,uid 和gid。然后是
IPC 对象的创建者的 uid 和gid。接下来的是IPC 对象的存取权限。最后一个成员也许有点
难于理解,不过不要担心,这是系统保存的IPC 对象的使用频率信息,我们完全可以不去
理会它。

原文链接:

http://blog.csdn.net/geng823/article/details/41009975