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 >