信号量?
程序中,有时存在一种特殊代码,最多只允许一个进程执行那部分代码,这部分区域代码称为"临界区"
然而在多进程并发执行时,当一个进程进入临界区,因某种原因被挂起时,其它进程就有可能也进入该区域
解决方法:使用信号量
什么是信号量?
信号量是一种特殊变量只能进行P,V操作,linux下的信号量是一种休眠锁
P: if 信号量>0,把信号量-1;else if 信号量=0,挂起该进程
V: 如果有进程因信号量挂起,则回复该进程,else 把信号量+1
注:信号量都是原子操作,即其在执行时,不会中断
计数信号量和二值信号量
它可以同时允许任意数量的拥有者,此时的值称为数量。通常情况下,信号量与自旋锁一样,在一个时刻仅允许拥有一个锁持有者。这时计数等于1,这样的信号量称为二值信号量或者称为互斥信号量,P,V来自于荷兰语Proberen和Vershigen后来的操作系统把这两个操作称为down和up
信号量的使用
int semget(key_t key,int nsems,int semflg)
获取一个已存在,或创建一个新的信号量,返回该信号的标识符
key: 该键值对应一个唯一的信号量。特殊键值: IPC_PRIVAT该信号量允许创建者本身
nsems: 需要的信号量数目,一般取1
semflg: 与共享内存的semflg类似IPC_CREAT,若该信号量未存在则创建信号量
int semop(int semid,struct sembuf* sops,unsigned nsops)
改变信号量的值,即进行P操作V操作
semid 信号量标识符
struct sembuf{
short sem_num;//信号量组中的编号
short sem_op;//-1表示P操作,1表示V操作
short sem_flg;//SEM_UNDO:如果进程在终止时,没有释放信号量应设置为0,否则释放
};//nspos 表述第二个参数数组的大小
int semctl(int semid,int sem_num,int cmd,...)
对信号量进行控制
sem_num信号量组中的编号 cmd: SETVAL把信号量初始化为指定的值,具体值由第四个参数确定
第四个参数为:union semum{
int val;
struct semid_ds* buf;
unsigned short* array;
}