重点:
P
1,每执行一次就会减1,减后小于0就要等待(即P(0)就要等待)
2,可以理解为是检查当前这个进程前面的所有东西是否处理好了,然后才到自己运行 。
V
1,每执行一次就加减1。
2,理解为当前进程运行好了,要通知下一个进程了。
题目一:
今有3个并发进程R、M、P,它们共享一个缓冲器B。进程R负责从输入设备读入信息,每读一个记录后把它存放在缓冲器B中。进程M在缓冲器B中加工进程R存入的记录。进程P把加工后的记录打印出来。缓冲器B中每次只能存放一个记录,当记录被加工输出后,缓冲器B中又可以存放一个新的记录。为协调它们的工作,采用PV操作进行管理,请写出R、M、P 三个并发进程的伪代码。要求写出详细的步骤。
信号量 s1=1,s2=0,s3=0;
R(){
while(1){
读入信息
P(s1); //看看是不是到自己运行
记录存入缓存器B中
V(s2); //通知下一个进程
}
}
M(){
while(1){
P(s2);
加工记录
V(s3);
}
}
P(){
while(1){
P(s3);
输出信息
V(s1); //继续通知开头那个进程,形成一个循环,持续工作
}
}
题目二:
(和题目一类似)
在一个盒子里,混装了数量相等的黑白围棋子。现在用自动分拣系统把黑子、白子分开,设分拣系统有两个进程P1和P2,其中P1拣白子,P2拣黑子。规定每个进程每次拣一子;当进程在拣时,不允许另一个进程取拣;当一个进程拣了一子时,必须让另一进程去捡。假设从拣白子开始。试写出P1和P2进程能正确并发执行的算法程序。要求写出详细的步骤
信号量 s1=1,s2=0;
P1(){
while(1){
P(s1);
拣白子
V(s2);
}
}
P2(){
while(1){
P(s2);
拣黑子
V(s1);
}
}
题目三
假定有一个成品仓库,总共能存放8台成品,生产者进程把生产成品放入仓库,消费者进程从仓库中取出成品消费。为了防止积压,仓库满时就停止生产。由于仓库搬运设备只有一套,故成品的存入和取出只能分别进行,试用P、V操作来实现该方案。要求写出详细的步骤。
信号量 s1=8,s2=0,mutex=1
producer(){
P(s1);//看看仓库还能不能装下成品,能就生产s1--,可以把s1看作仓库剩余的空间
生产产品
P(mutex);//搬运设备互斥资源,加锁
搬运
V(mutex);//用完,解锁
V(s2); //通知消费者可以来拿东西
}
consumer(){
P(s2);//看看有没有人通知我拿东西
P(mutex);
搬运
V(mutex);
V(s1); //通知生产者,我拿东西了,仓库剩余空间+1
}
题目四
某自动质量检测系统有三个进程Q、A、B组成。进程Q每次取一件产品检测,把检测后的产品存放在货架F上,F的容量为每次只能存放一件产品。若货架上存放的是合格产品则让进程A取出,并在产品上贴标签后包装;若货架上存放的是不合格产品则让进程B取出后,将其丢入废物箱。
请写出用PV操作管理时应定义的信号量及初值以及相应的操作,使它们能按上述要求正确地并发执行。
信号量 a=0,b=0,empty=1
Q(){
取一件产品检查
P(empty);//检测货架是否位置
放在货架F上
if(产品合格){ //如果合格产品,通知a
V(a);
}
else{
V(b)//否则通知b
}
}
A(){
P(a);//检测是否有自己的工作
取货架F的产品
V(empty);//拿走产品,位置+1
对产品贴标签且包装
}
B(){
P(b);
取货架F的产品
V(empty);
把产品丢入废物箱
}
题目五
三个进程 P1、P2、P3 互斥使用一个包含 N(N>0)个单元的缓冲区。P1 每次用 produce() 生成一个正整数并用 put()送入缓冲区某一个空单元中;P2 每次用 getodd()从该缓冲区中 取出一个奇数并用 countodd()统计奇数个数;P3 每次用 geteven()从该缓冲区中取出一个 偶数并用 counteven()统计偶数个数。请用信号量机制实现这三个进程的同步与互斥活动, 并说明所定义的信号量的含义。
信号量 even=0,odd=0,empty=N,mutex=1;
int num;
P() {
while(1) {
P(empty); //检测是否还有位置
num=produce();
P(mutex);//实现缓冲器互斥
put();
V(mutex);
if(num%2==0) {
V(even);//通知偶数的线程
} else {
V(odd);//通知奇数的线程
}
}
}
P2() {
while(1) {
P(odd); //看看有没有自己奇数的任务
P(mutex);//用到缓冲器,要互斥
getodd();
countodd();
v(mutex);
v(empty);//取出一个数,位置+1
}
}
P3() {
while(1) {
P(even);
P(mutex);
geteven();
counteven();
V(mutex);
V(empty);
}
}
题目六
一个野人部落从一个大锅中一起吃炖肉,这个大锅一次可以存放 M 人份的炖肉。当野人 们想吃的时候,如果锅中不空,他们就自助着从大锅中吃肉。如果大锅空了,他们就叫 醒厨师,等待厨师再做一锅肉。 野人线程未同步的代码如下: while (true){ getServingFromPot(); eat() } 厨师线程未同步的代码如下: while (true) { putServingsInPot(M) } 同步的要求是: 当大锅空的时候,野人不能够调用 getServingFromPot() 仅当大锅为空的时候,大厨才能够调用 putServingsInPot() 问题:请写出使用 PV 满足同步要求的完整程序。
//假设一开始锅为空,让厨师煮才有
信号量 empty=1,haveFood=0;
int food=0;
//empty 和 haveFood 分别表示厨师阻塞等待和野人阻塞等待的条件
wildMan(){
P(haveFood); //检查是否有食物,且锁锅
getServingFromPot();//拿食物
food--;//食物数量-1
eat();//吃
if(food==0){
V(empty); //没有食物了,通知厨师煮
}
else{
V(haveFood); //解锅
}
}
cook(){
P(empty); //看看自己有没有煮饭任务
putServingInPot(M);
food += M;//煮一锅
V(haveFood);//v后 +1,让野人检查到锅里有食物(野人通知厨师后没有解锅,厨师要帮忙解锅
}
题目七
桌子上有一只盘子,最多可容纳两个水果,每次只能放一只水果,爸爸专向盘子中放苹果,妈妈专向盘子中放橘子,两个儿子专等吃盘子里的橘子,两个女儿专等吃盘子里的苹果。写出能使爸爸、妈妈、儿子、女儿正确同步工作的PV过程。
信号量 mutex=1,empty=2,apple=0,orange=0
father(){
while(1){
P(empty);//看看是否还有位置放水果
P(mutex);//对盘子加锁
放一个苹果
V(mutex)//解锁
V(apple)//通知拿苹果的人
}
}
mother(){
while(1){
P(empty);
P(mutex);
放一个桔子
V(mutex)
V(orange);
}
}
son(){
while(1){
P(orange);
P(mutex);
拿一个桔子
V(mutex);
V(empty);
}
}
daughter(){
while(1){
P(apple);//检查自己有没有被通知拿苹果
P(mutex);//加锁
拿一个苹果
V(mutex);//解锁
V(empty);
}
}