信号量操作结构体的定义如下:
struct sembuf
{
unsigned short sem_num; /* 信号量元素序号(数组下标) */---空间0 数据1
short sem_op; /* 操作参数 *-----PV操作
short sem_flg; /* 操作选项 */----->普通属性,填0
};
请注意:信号量元素的序号从 0 开始,实际上就是数组下标
根据 sem_op 的数值,信号量操作分成 3 种情况:
A) 当 sem_op 大于 0 时:进行 V 操作,即信号量元素的值(semval)将会被加上sem_op 的值。
C) 当 sem_op 小于 0 时:进行 P 操作,即信号量元素的值(semval)将会被减去sem_op 的绝对值。
共享内存以及互斥信号量的使用
第一步,先申请key值(类比文件路径名)
key_t key=ftok(".",25);
第二步,根据申请的key值去申请共享内存的ID号->shmget --->man 2 shmget (类比文件描述符)
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);---->share memory get
参数1:key值
参数2:size----->共享内存总字节数,必须是PAGE_SIZE(1024)的整数倍 #define PAGE_SIZE 1024
参数3:IPC_CREAT|0666
返回值:成功返回:共享内存的ID号
失败:-1
第三步,根据ID号将共享内存的映射至本进程虚拟机内存空间的某一个区域
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
参数1:共享内存的ID
参数2:shmaddr--->NULL(系统自动给你分配) 不为NULL-->用户自己去选择地址
参数3:shmflg----->普通属性,填0
返回值:成功:虚拟共享内存的的起始地址
失败:(void *)-1
第四步,当不在使用时,解除映射
int shmdt(const void *shmaddr);
参数:shmaddr--->你需要解除虚拟内存映射的地址
返回值:成功返回0
失败返回-1
第五步,当没有进程再需要使用这块共享内存,删除它-->shmctl--->man 2 shmctl
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数1:shmid----->共享内存的ID
参数2:cmd------->操作命令 IPC_STAT(获取属性的信息),必须填第3个参数
IPC_RMID(删除共享内存)--->第3个参数填NULL
参数3:buf---->填什么需要看参数2-->cmd
返回值:成功返回0
失败返回-1
shmctl(shmid, IPC_RMID, NULL);
第六步,由于信号量属于IPC对象,申请key值
key=ftok(".",20);
第七步,根据key值申请信号量ID号-->semget --->man 2 semget
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
参数1:key--->信号量的key值
参数2:nsems--->信号量元素的个数。例如:空间+数据->2