信号量机制是一种用于控制多进程或者多线程并发访问共享资源的同步机制。信号量实质上是一个整型计数器,通常用于表示可用资源的数量或许可证的数量,类似于一个整型的全局变量。不同于一般的整型变量,对信号量的操作只有两个:P操作和V操作
P操作即wait操作,为进程申请一个资源S,S相应的信号量的值减一。若此时没有资源S可以给该进程使用,则进程阻塞等待。
V操作即signal操作,释放一个资源S,S相应的信号量的值加一。若此时有进程正在等待资源S,则唤醒该进程。
整形信号量
整形信号量是最简单的一种信号量,基本代码如下
void wait(int S)
{
while(S<=0);
/*当S小于等于零时,do nothing,此时想访问临界资源的进程需要等待;直到S大于零时,若有申请访问临界资源的进程,则信号量减一。*/
S--;
}
void signal(int S)
{
S++:
}
wait操作:当S小于等于零时,do nothing,此时想访问临界资源的进程需要等待;直到S大于零时,若有申请访问临界资源的进程,则信号量减一。while循环中的条件判断不断地检查信号量S的值,直到S大于0为止。这意味着所有申请访问该资源的进程都必须等待直到资源可用。
signal操作:wait操作和signal操作必须成对出现。进程访问完某资源后,要释放它。
整形信号量虽然简单易懂,但容易形成忙等。进程占有处理机,但一直在判断S是否大于零,而S又始终小于等于零,形成死循环,不能再往下执行。
记录型信号量
typedef struct
{
int value;//整型变量记录资源数
struct process*L;//阻塞队列(等待队列)
}
void wait(semaphore S)
{
S.value--;
if(S.value<0)
block(S,L);//block原语使进程从运行态进入阻塞态
}
void signal(semaphore S)
{
S.value++;
if(S.value<0)
wakeup(S,L);//wakeup原语唤醒阻塞等待的进程
}
wait操作:直接预定了资源,使信号量减一。若预定后资源量大于零,说明肯定有富余,可以分配,不必等待;若预定后资源量等于零,说明在预定前正好资源数目为1,正好分给该进程,不必等待;若预定后资源量小于零,说明在预定前资源量已经小于或等于零了,没有多余的量分给该进程了,需要等待;
signal操作:当有程序用完该资源后,对信号量进行释放时,S.value++.若信号量值加一后不大于零,说明此前有进程预定了该资源。这时,从阻塞队列里唤醒预约了当前资源的进程,进行分配。
标签:操作系统,信号量,预定,进程,操作,千字,资源,wait From: https://blog.csdn.net/2301_76172693/article/details/137223391