操作系统PV操作

116 阅读3分钟

PV操作基本框架

semaphore mutex=1,empty=5,full=0;

main(){
	cobegin
		PA();
		PB();
		PC();
	coend
}

PA(){
	while(1){ //存在,看是否有多次调用需要
		***
	}
}

PB(){
	while(1){
		***
	}
}

1.生产者和消费者问题

/*设有一个可以装A、B两种物品的仓库,其容量无限大,但
要求仓库中A、B两种物品的数量满足下述不等式:
• -M≤A物品数量-B物品数量≤N 
• 其中M和N为正整数. 
§ 试用信号量和PV操作描述A、B两种物品的入库过程.*/

/*分析:A入库——必然导致B最大值增加,但A能够入库的要求为当前库中A数量小于(B数量+N);B入库同理*/

Semaphore mutex = 1,sa = N,sb = M;
procedure Awhile(1)
    begin
    P(sa)
		P(mutex)
		A get stored
    V(mutex)
		V(sb)
procedure Bwhile(1)
    begin
    P(sb)
		P(mutex)
    B get stored
    V(mutex)
    V(sa)
/*
三个进程P1、P2、P3 互斥使用一个包含N(N>0)个单元的缓冲区。
P1 每次用produce()生成一个正整数并用put()送入缓冲区某一个空单元中;
P2 每次用getodd()从该缓冲区中取出一个奇数并用countodd()统计奇数个数;
P3 每次用 geteven()从该缓冲区中取出一个偶数并用counteven()统计偶数个数。
请用信号量机制实现这三个进程的同步与互斥活动,并说明所定义的信号量的含义。*/

Semaphore mutex = 0,empty = N,odd = 0,even = 0
int number = 0
P1:
while(True)
number = produce()
P(empty)
P(mutex)
put()
v(mutex)
if(number%2==0):
	V(even)
else:
	V(odd)

P2:
cobegin:
while(True)
P(odd);
P(mutex);
getodd();
V(mutex);
V(empty);
countodd();

P3:
cobegin:
while(True)
P(even);
P(mutex);
geteven();
V(mutex);
V(empty);
counteven();

读者写者问题

//读者优先
int readers = 0;//读者计数器
Semaphore mutex = 1;
Semaphore roomEmpty = 1;//写者“写”信号
writer:
  while(1){
    P(roomEmpty);//写者互斥、写者-读者互斥
      writing;//写文件
    V(roomEmpty);//写操作完成
  }
reader:
  while(1){
    
    P(mutex);//互斥操作读者计数器
    if(readers==0){
      P(roomEmpty);//第一个读者进临界区,加锁
    }
    readers++;//读者可同步访问共享数据
    V(mutex);
    
    read;
    
    P(mutex);
    readers--;
    if(readers==0){
      V(roomEmpty);//读者全部读完,解锁
    }
    V(mutex);
  }
//共享读;互斥写、互斥读写;写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)--FIFO
int readers = 0;//读者计数器
Semaphore mutex = 1;
Semaphore roomEmpty = 1;//互斥访问
semaphore w = 1;//写者优先
write:
	while(1){
    P(w);
    P(roomEmpty);
    writing;
    V(roomEmpty);
    V(w);
  }
readers:
	while(1){
    P(w);//之前是否有写者排队
    P(mutex);
    if(readers==1){
      P(roomEmpty);
    }
    readers++;
    V(mutex);
    V(w);
    reading;
    P(mutex);
    readers--;
    if(readers==0){
      V(roomEmpty);
    }
    V(mutex);
  }
哲学家进餐问题

思路:当且仅当哲学家能同时拿起左右两边的筷子时,哲学家拿起筷子并就餐,但是不能简单地将该问题简化为两次申请筷子的操作——每个哲学家都执行一次申请后,再无空闲筷子可分配,造成死锁,解决方法

semaphore mutex[5]={1,1,1,1,1}//5只筷子,互斥访问
semaphore count = 4;//最大可同时申请进餐的哲学家数——>不形成环路的最大值
philosopher(int i){
while(true){
  //thinking
	P(count);
  P(mutex[i]);
  P(mutex[(i+1)%5]);
  //eating
  V(mutex[i]);
  V(mutex[(i+1)/5]);
  V(count);
}