System V IPC基础

来源:互联网 发布:庞氏骗局 知乎 编辑:程序博客网 时间:2024/06/05 03:13

一、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.hkey_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;};
原创粉丝点击