本质上就是共享资源的数目,用来控制对共享资源的访问。
用于进程间的互斥和同步。
每种共享资源对应一个信号量,为了便于大量共享资源的操作引入了信号量集,可对所有信号量一次性操作。对信号量集中所有操作可以要求全部成功,也可以部分成功。
二元信号量的值为0和1。
对信号量做PV操作。
int semget(key_t key,int nsems,int flag)
成功返回信号量集ID,出错返回-1。
nsems信号量集信号灯个数。
int semctl(int semid,int semnum,int cmd,...)
int semop(intsemid,struct sembuf *sops,size_t nsops)
成功返回0,失败返回-1。
用于信号集中的加和减操作(PV操作)。
用于进程间的互斥和同步。
将信号量操作进行封装,在进程事件中直接调用。
头文件:
/*************************************************************************
> File Name: pv.h
> Author: CC
> Mail: 6828620@163.com
> Created Time: 2018年09月11日 星期二 22时18分27秒
************************************************************************/
#ifndef __PV_H__
#define __PV_H__
//初始化semnums个信号灯的直
extern int I(int semnums,int value);
//对信号量集(semid)中的信号灯(semun)作P(value)操作
extern void P(int semid,int semnum,int value);
//对信号量集(semid)中的信号灯(semun)作V(value)操作
extern void V(int semid,int semnum,int value);
//销毁信号量集(semid)
extern void D(int semid);
#endif
函数实现:
/*************************************************************************
> File Name: pv.c
> Author: CC
> Mail: 6828620@163.com
> Created Time: 2018年09月11日 星期二 22时28分27秒
************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<sys/sem.h>
#include<string.h>
#include<assert.h>
#include<malloc.h>
#include"pv.h"
union semun{
int val;
struct semid_ds *buf;
unsigned short *array;
};
//初始化semnums个信号灯的直
int I(int semnums,int value)
{
//创建信号量集
int semid = semget(IPC_PRIVATE,semnums,IPC_CREAT|IPC_EXCL | 0777);
if(semid < 0){
perror("semget error!\n");
exit(1);
}
union semun un;
unsigned short *array = (unsigned short)calloc(semnums,sizeof(unsigned short));
int i;
//数组初始化
for(i = 0; i < semnums; i++){
array[i] = value;
}
un.array = array;
//初始化信号量集中所以信号灯的初值。0表示初始化所有信号灯,SETALL表示
if(semctl(semid,0,SETALL,un) < 0){
perror("semctl error");
return -1;
}
free(array);
return semid;
}
//对信号量集(semid)中的信号灯(semun)作P(value)操作
void P(int semid,int semnum,int value)
{
assert(value >= 0);
//定义sembuf的结构体数组,放置若干结构体变量,对应要操作的信号量/作P或V操作。
struct sembuf ops[] = {{semnum,-value,SEM_UNDO}};
if(semop(semid,ops,sizeof(ops)/sizeof(struct sembuf)) < 0){
perror("semop error");
}
}
//对信号量集(semid)中的信号灯(semun)作V(value)操作
void V(int semid,int semnum,int value)
{
assert(value >= 0);
//定义sembuf的结构体数组,放置若干结构体变量,对应要操作的信号量/作P或V操作。
struct sembuf ops[] = {{semnum,value,SEM_UNDO}};
if(semop(semid,ops,sizeof(ops)/sizeof(struct sembuf)) < 0){
perror("semop error");
}
}
//销毁信号量集(semid)
void D(int semid)
{
if(semctl(semid,0,IPC_RMID,NULL) < 0){
perror("semctl error!\n");
exit(1);
}
}