System V IPC基础

一、System V IPC基础

  System V提供的IPC机制主要有:消息队列信号量共享内存 3种机制。和文件一样,IPC在使用前必须先创建,每种IPC都有特定的生产者、所有者、和访问权限。使用ipcs命令可以查看当前系统正在使用的IPC工具,可以作为调试程序的一个重要手段
  这里写图片描述
  
  由上图可以看出,一个IPC工具至少包含key值、ID值、拥有者、权限和使用的大小等关键信息。如果需要手工删除某个IPC机制,可使用ipcrm命令

二、key值和ID值

  Linux系统为每个IPC机制都分配了唯一的ID,所有针对IPC机制的操作都使用该ID值。通信双方都需要通过某个方法来获取ID值。为了解决这一问题,IPC在实现时约定使用key值做为参数创建,如果在创建时使用相同的key值将得到同一个IPC对象的ID(即一方创建ID,另一方仅仅是获取ID),这样就保证了双方可以获取用于床底数据的IPC机制ID值。其中key值是一个32位的整型数据。
  key值有两种途径获取:1.key值可以人为的指定。但这样可能会造成同一个IPC机制有相同的可以值,为了解决这个问题Linux系统提供了系统调用。2.ftok()可以创建key。此函数的声明如下:

// come from /usr/include/sys/ipc.h
key_t ftok(const char* pathname, int id);

  第1个参数pathname为文件路径,可以是普通文件路径也可以是目录路径,但必须为当前系统存在的路径;
  第2个参数id为一个int型变量。
  
  每个文件都有其自身的属性,可以通过stat()函数读取,在ftok()函数创建key时,使用了该文件属性的st_dev(文件设备编号)和st_ino(文件节点),key的具体构成如下所示:

key值的31~24(共8bit)为ftok()第2个参数的低8位;
key值的23~16(共8bit)为该文件st_dev属性的低8位;
key值的15~0(共16bit)为该文件st_ino属性的低16位。

  因此,ftok()使用相同的参数将得到的key是完全相同的。同一个key值创建某类IPC机制将得到同一个IPC机制。可以使用相同key值创建的不同类的IPC,即使用相同的key值分别创建一个消息队列和一下信号量,两者是没有联系的。下面给出使用ftok()创建key值的示例:

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

#define PATHNAME    "/"

int main()  
{  
    key_t key;
    struct stat buf;

    if (stat(PATHNAME, &buf) == -1) {
        perror("stat error");
        return -1;
    }

    printf("file st_dev:%x\n", buf.st_dev);
    printf("file st_ino:%x\n", buf.st_ino);

    key = ftok(PATHNAME, 3);

    printf("\nkey=%x\n", key);

    printf("key>>24=%x\n", key>>24);
    printf("(key>>16)&0xff=%x\n", (key>>16)&0xff);  // st_dev
    printf("key&0xffff=%x\n", key&0xffff);          // st_ino

    return 0;
}

运行结果如下所示:
这里写图片描述

  上图运行结果完全符合key值的构成。

三、拥有者及权限

  要访问任何一个IPC工具需要对该IPC工具拥有相应的权限,该结构为struct ipc_perm定义在/usr/include/bits/ipc.h文件中。具体实现如下:

/* Data structure used to pass permission information to IPC operations.  */
struct ipc_perm
{
    __key_t __key;                  /* Key.  */                     // Key值
    __uid_t uid;                    /* Owner's user ID.  */         // 拥有者ID
    __gid_t gid;                    /* Owner's group ID.  */        // 拥有者组ID
    __uid_t cuid;                   /* Creator's user ID.  */       // 创建者ID
    __gid_t cgid;                   /* Creator's group ID.  */      // 创建者组ID
    unsigned short int mode;        /* Read/write permission.  */   // 读写权限
    unsigned short int __pad1;
    unsigned short int __seq;       /* Sequence number.  */
    unsigned short int __pad2;
    __syscall_ulong_t __glibc_reserved1;
    __syscall_ulong_t __glibc_reserved2;
};
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值