system IPC

ftok函数原型如下:

#include <sys/ipc.h>

key_t ftok(const char *pathname, int id)

说明:
1. 内核通过 key_t 类型(通常为32为整形)来标识一个 system v ipc 对象。
2. key_t 类型 变量的值由以下 3 部分(各取部分)拼接而成:
    ○ pathname 所指定文件的 stat 结构的 st_dev 成员
    ○ pathname 所指定文件的 stat 结构的 st_ino 成员
    ○ id 最低 8 位(id 参数只用到最低 8 位)
3. pathname指定的路径名必须存在,否则返回 -1



ipc_perm Structure

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 */ (linux下为 __seq)
};

说明:
1. 内核为每一个 system v ipc 对象提供一个 ipc_perm 结构体对象来记录其权限和模式等相关信息。
2. 创建 system v ipc 对象时指定的 mode 不受 umask 的影响。
3. 结构体中的 seq 解释为 /* slot usage sequence number */,整个 system v ipc可以理解为一个对象池,每次创建一个资源时, 分配一个 slot ,seq 标识该 slot 第几次使用(每使用一次加 1 , 溢出时 回复到 0)
实例:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

union semun{
        int val;
        struct semid_ds * buf;
        unsigned short int * array;
        struct seminfo * __buf;
};
#if 0
struct ipc_perm
{
 __kernel_key_t key;
 __kernel_uid_t uid;
 __kernel_gid_t gid;
 __kernel_uid_t cuid;
 __kernel_gid_t cgid;
 __kernel_mode_t mode;
 unsigned short seq;
};
#endif
int main(int argc,char* argv[])
{
 int semid;
 pid_t pid;
 int proj_id;
 //system ipc 使用整数32位作为他们的名字
 key_t key; 
 int num;
 int i,j;

 union semun arg;

 static struct sembuf acquire={0,-1,SEM_UNDO};
 static struct sembuf release={0,1,SEM_UNDO};

 if(argc!=2){
  printf("Usage : %s num\n",argv[0]);
  return -1;
 }

 num=atoi(argv[1]);

 proj_id=2;
 //把一个存在的路径和一个整数标示符组合成key_t 称为IPC键
 key=ftok("/home/sifang",proj_id);
 if(key==-1){
  perror("cannot generate the IPC key");
  return -1;
 }
    //若key=IPC_PRIVATE 则保证创建一个新的,唯一的IPC对象
 semid=semget(key,1,IPC_CREAT | IPC_EXCL | 0666);
 if(semid==-1){
  perror("cannot create semaphore set");
  return -1;
 } 

 static unsigned short start_var=1;
 arg.array=1;
 if(semctl(semid,0,SETVAL,arg)==-1){
  perror("cannot set semaphore set");
  return -1; 
 } 

 for(i=0;i<num;i++){
  pid=fork();

  if(pid<0){
   perror("cannot create new process");
   return -1;
  }else if(pid==0){
   semid=semget(key,1,0);
   if(semid==-1){
    perror("cannot let the process get the access right");
    _exit(-1);
   } 

   for(j=0;j<2;j++){
    sleep(i);

// 即P操作,申请资源
    if(semop(semid,&acquire,1)==-1){
     perror("cannot acquire the resource");
     _exit(-1);
    }

    printf("====enter the critical section=====\n");
    printf("---pid : % ld ---\n",(long)getpid());
    sleep(1);
    printf("====leave the critical section=====\n");

//V操作

    if(semop(semid,&release,1)==-1){
     perror("cannot release the resource");
     _exit(-1);
    }
   }
   _exit(0);
  }
 }

 for(i=0;i<num;i++)
  wait(NULL);

 if(semctl(semid,0,IPC_RMID,0)==-1){
  perror("cannot remove the semaphore set");
  return -1;
 }

 return 0;
}


ipcs and ipcrm

1. ipcs 命令用来查看所有活跃的 IPC 资源,其格式如下:
      ipcs < -q | -s | -m | -l >
其中, -l 表示查看 IPC 资源的系统限制。
2. ipcrm 命令则是用来删除 IPC 资源,其格式如下:
      ipcrm < -q | -s | -m > < IPC ID >

你可能感兴趣的:(system IPC)