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 A:
while(1)
begin
P(sa)
P(mutex)
A get stored
V(mutex)
V(sb)
procedure B:
while(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);
}