说在前:①信号量机制是对具体物理资源的抽象②同类资源的个数用>0的信号量值来表示③0或1的则为临界资源
1、整型信号量
1.1 Dijkstra将其用于表示资源数目S,主要通过P(wait)、V(signal)操作访问。
P操作申请资源
wait(S){
while(S<=0); /判断有无资源 /
S- -;
}
V操作释放资源
signal(S){
S++;
}
2、记录型信号量
2.1 定义:是采取了“让权等待”策略的信号量,避免了上述信号量导致的“死等”现象
2.2 结构:
- S>0 ——>空闲;
- S=0 ——>忙碌;
- S<0 ——>都忙;
2.3 代码:
typedef struct{
int value;//资源个数
struct process_control_block *list;//阻塞队列
}semaphore;
wait(semaphore *S){
S ->value--;//资源先-1
if(S ->value<0)block(S ->list);//资源个数<0则排入阻塞队列
}
signal(semaphore *S){
S ->value++;//资源先+1
if(S ->value<=0)wakeup(S ->list);//资源个数<=0则唤醒进程
}
3、AND型信号量
3.1 基本思想:进程整个运行过程需要的资源一次性全部分配,使用完后在一起释放(资源利用率低)
3.2 代码:
Swait(S1,S2,...,Sn){
while(true)
{
if(Si>=1&&Sn>=1){//i为变量,n为总资源个数
for(i=1;i<=n;i++)Si--;//做循环,只要进程需要几个资源就分配给几个
break;
}
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 begining of Swait operation
}
}
}
Ssignal(S1,S2,...,Sn){
while(true){
for(i=1;i<=n;i++){
Si++;//做循环,释放出一个资源则资源个数+1
Remove all the process waiting in the queue associated with Si into the ready queue
}
}
}
4、信号量集
4.1 基本思想:一次申请多个资源,每次分配前都要测试资源数目,根据可分配下限值决定是否分配
4.2 定义格式
Swait(S1,t1,d1,…,Sn,tn,dn);
Ssignal(S1,d1,…,Sn,dn);
例:应用信号量实现同步与互斥
互斥:
semaphore mutex=1;//mutex为互斥信号量
Pa(){
while(1){
wait(mutex);
临界区;
signal(mutex);
剩余区;
}
}
Pb(){
while(1){
wait(mutex);
临界区;
signal(mutex);
剩余区;
}
}
- mutex=1,两进程皆未进入互斥临界区
- mutex=0,一进程进入临界区,另一进程阻塞队列
- mutex=-1,一进程正在临界区运行,另一进程阻塞队列,需运行进程退出时唤醒
同步:
Semaphore s=0; //初始化信号量
P1(){
…
x; //语句x
V(s) ; //告诉进程P2,语句x已经完成
…
}
P2(){
…
P(s) ; //检查语句x是否运行完成
y; //检查无误,运行语句y
…
}
同步互斥综合应用
多缓冲池生产者消费者问题
int in=0,out=0;
item buffer[n];
semaphore:mutex=1,empty=n,full=0;
void producer(){
producer
do{
producer an item nextp;
...
wait(empty);
wait(mutex);
buffer[in]=nextp;
in=(in+1)%n;
signal(mutex);
signal(full);
}while(true);
void consumer(){
do{
wait(full);
wait(mutex);
nextc=buffer[out];
out=(out+1)%n;
signal(mutex);
signal(empty);
consumer the item in nextc;
...
}while(true);
void main(){
cobegin
producer(); consumer();
coend;}