信号量(Semaphore)是Dijkstra在1965年提出的进程同步机制,表示临界资源的实体。用于解决进程的同步和互斥问题。
信号量的分类:
整形信号量、记录型信号量、AND型信号量、信号量集
一、整形信号量
信号量定义为一个整型量S,S≤0表示资源已被占用,S>0表示资源可用。
//申请资源操作原语
wait(int &S){ // P(S)
while(S<=0); //S不够时阻塞进程
S=S-1;
}
//释放资源操作原语
signal(int &S){ //V(S)
S=S+1;
}
//上面两个即P、V操作
应用示例:
int S=1;
void *p1(void *p){
.....
wait(S);
.....
signal(S);
.....
}
void *p2(void *p){
.....
wait(S);
.....
signal(S);
.....
}
//存在问题,当S<0时,会让进程进入忙待状态
不足:当S<=0时,就要不断检测。陷入“忙等”状态,不符合让权等待。
二、记录型信号量
typedef struct{
int value;
list<PROC> L;
}semaphore;
//value>0时,value为资源可用数目
//L为阻塞进程队列首指针
wait(int &S){
S.value--;
if(S.value<0);
block(S.L); //阻塞到队尾
}
signal(int &S){
S.value++;
if(S.value<=0);
wake(S.L);
}
/*若加1后仍是S.value<=0,则表示在S.L中仍有等待该资源的进程被阻塞
故还应调用wakeup 原语,将S.L中的第一个等待进程唤醒。*/
不足:同整型信号量一样,都是正对的是共享一种临界资源。 若一个进程需要两个或更多资源后才可执行,就会出现死锁的可能,共享资源越多,进程死锁可能性越大。
三、AND型信号量
AND同步机制:要么把进程在整个运行过程中所请求的资源全部分配到进程(进程使用完成后一起释放),要么一个也不分配。
wait(S1,S2,...,Sn) {
if(S1>=1 and … and Sn>=1) {
for(i:=1 to n)
Si--;
} else {
place the process in the waiting queue associated with the first Si found with Si<1,and set the program count of this process to the beginning of Swait operation
}
}
signal(S1,S2,...,Sn) {
for(i:=1 to n) {
Si++;
Remove all the process waiting in the queue associated with Si into the ready queue.
}
}
</