信号量 :可以理解为一种临界资源的计数器,一般将信号量设置为>0的值
表示该资源还要几个可以直接用 对应的操作还要是PV操作
其中p代表可用资源-1 v代表可用资源+1
临界区:用来访问或者操作临界资源的代码
信号量集:包含多种临界资源的,对多种临界资源进行描述。
模拟一个信号量的基本操作: (玩具代码)
//Sem.h
Union semun
{
Int val;//信号量初始值
};
Void sem_init(int a[],int n);
Void sem_p(int index);
Void sem_v(int index);
Void sem_del();
//Sem.c
#include”sem.h”
static int semid=-1;
void sem_init(int a[], int n)
{
semid = semget((key_t)1234, 2, IPC_CREAT | IPC_EXCL | 0600);
//写端和读端哪个先执行还不确定 到底是全新创建还是使用已经存在的还不确定
if (semid == -1) //已经存在读端(写端)已创建好
{
semid = semget((key_t)1234, 2, 0600);//只需要获取创建好的信号量
if (semid == -1)
{
perror("get sem error");
}
}
else {
union semun b;
int i = 0;
for (; i<n; ++i)
{
b.val = a[i];
if(semctl(semid, i, SETVAL, b) == -1)
{
perror("semctl error");
}
}
}
}
void sem_p(int index)
{
struct sembuf buf;
buf.sem.num = index;
buf.op = -1; //p
buf.sem_flg = SEM_UNDO;
if(semop(semid, &buf, 1) == -1)
{
perror("semop error");
}
}
void sem_v(int index)
{
struct sembuf buf;
buf.sem.num = index;
buf.op = 1; //v
buf.sem_flg = SEM_UNDO;
if(semop(semid, &buf, 1) == -1)
{
perror(“semop error”);
}
}
void sem_del()
{
if(semctl, 0, IP_RMID) == -1)
{
perror("semctl del error");
}
}