引言:P,V操作必须成对出现,P可简单的理解为消耗一种资源,V可简单的理解为增加一种资源。
1.用信号量实现互斥
semaphore S=1;//定义一个互斥信号量
P1(){
P(S);//加锁
进入临界区
V(S);//解锁
}
2.用信号量实现同步(先发生的V在前后发生的P在前)
semaphore S=0;
P1(){ P2(){ P(S);y ;}
x;
V(S);
}
经典同步问题
1.生产者消费者问题
一组生产者和消费者共享大小为n的缓冲区,只有缓冲区不空时消费者才能从中取出产品,只有缓冲区不满时生产者才能往缓冲区放入产品。(缓冲区同时只允许一个生产者,或一个消费者从中增加或取出一个产品)。
问题分析:首先有两个进程,不妨设进程P1为生产者,P2为消费者。P1生产产品,检查缓冲区是否已满,放入产品。P2检查缓冲区是否有产品,取出产品。
伪代码:
semaphore mutex=1;//设置一个互斥信号量
semaphore empty=n;//空闲缓冲区总量
semaphore full=0;//产品数量
P1(){
while(1){
生产产品;
P(empty);//消耗一个空闲缓冲区
P(mutex);//实现互斥·访问缓冲区
放入缓冲区;
V(mutex);
V(full);//增加缓冲区一个产品的数量
}
}
P2(){
while(1){
P(full);//缓冲区产品减一
P(mutex);//实现互斥·访问缓冲区
取走一个产品;
V(mutex);
V(empty);//增加空闲缓冲区的数量
}
}
2.多生产者多消费者问题
桌子上有一个盘子,一次只能放一个水果,爸爸往盘子中放苹果,妈妈往盘子中放橘子。儿子只能从盘子中拿走橘子并吃掉,女儿只能从盘子中拿走苹果并吃掉。(只有盘子为空时爸爸妈妈才能放入水果,只有盘子里有自己需要的水果时,儿子女儿才能拿走)。
问题分析:一共四个进程,爸爸,妈妈,儿子,女儿,爸爸往盘子中放苹果,妈妈往盘子中放橘子,儿子从盘子中拿橘子,女儿从盘子中拿苹果
伪代码
semaphore plate=1,apple=0,orange=0;
dad(){
while(1){
p(plate);//互斥访问盘子
放苹果
v(apple);//允许取苹果
}
}
mom(){
while(1){
p(plate);
放橘子;
v(orange);
}
}
son(){
while(1){
p(orange);//取橘子
取走橘子
v(plate);//释放盘子(解锁)
吃掉;
}
}
daughter(){
while(1){
v(apple);
取走一个苹果;
v(plate);
吃掉;
}
}