参考
《王道-操纵系统》
概述
信号量机制用于解决同步和互斥的问题,它通过两个原语 wait 和 signal 实现,也可以表示为 p,v。其中 wait 是申请资源,signal 是释放资源。
整型信号量
整型信号量是将信号量定义为整型 S
wait(S)
{
// 如果资源数小于 0 则陷入忙等
while(S<=0);
S=S-1;
}
signal(S)
{
S=S+1;
}
可以看到,整型信号量并未遵循让权等待,而是会出现忙等的情况
记录型信号量
所谓记录型,就是信号量采用结构体的方式进行定义,相比于整型信号量,其优势在于不会陷入忙等状态,因为在信号量中,设置了等待队列
typedef struct
{
int value;
struct process *L;
}semaphor;
void wait(semaphor S)
{
S.value--;
if(S.value<0)
{
add this process to S.L;
// block 原语,用于进行自我阻塞
block(S.L);
}
}
void signal(semaphor S)
{
S.value++;
// 如果资源被释放了,而就绪队列中还有其他等待进程
// 则唤醒其他等待进程
if(S.value<=0)
{
remove a process P from S.L;
wakeup(P);
}
}
利用信号量实现同步
P2程序的 y 语句需要 P1程序的 x 语句执行完后,才能启用,这里使用 S 来确定程序执行顺序的问题
semaphor S=0;
P1()
{
x;
v(S);
}
P2()
{
P(S);
y;
}
信号量实现互斥
使用互斥量完成对临界区的互斥访问
semaphor S=1;
P1()
{
P(S);
进入临界区;
V(S);
}
P2()
{
P(S);
进入临界区;
V(S);
}