10-os考研题目
改题目中p0,p1两个进程可以互斥的进入临界区,会出现饥饿现象(答案给的是D,但是自我认为可以出现饥饿现象)
互斥的访问:
p0: Flag[0]=TRUE;
p1: Flag[1]=TRUE;
p1: turn=0;
p1: While (flag[0] && (turn==0)); // p1 会一直循环
p0: turn=1;// 此时的p1循环条件不满足,进入临界区
p0: While (flag[1] && (turn==1)); //p0 会一直循环
当p1从临界区出来是flag[1] =false;p0的循环条件不满足p0进入临界区
上述过程完成了p1先进入临界区,之后p0进入临界区,互斥的访问。
这个过程中turn是共享变量,因此一次只能是一个值,一个满足继续循环,一个不满足必然要进入临界区。
存在饥饿:
p0: Flag[0]=TRUE;
p1: Flag[1]=TRUE;
p1: turn=0;
p1: While (flag[0] && (turn==0));//p1 空等
p0: turn=1;
p0: While (flag[1] && (turn==1));//p0 空等
11-os考研
某银行提供1个服务窗口和10个顾客等待座位。顾客到达银行时,若有空座位,则到取号机领取一个号,等待叫号。取号机每次仅允许一个顾客使用。当营业员空闲时,通过叫号选取一位顾客,并为其服务。顾客和营业员的活动过程描述如下:
cobegin{
process 顾客i
{
从取号机获得一个号码;
等待叫号;
获得服务;
}
process 营业员
{
while(true)
{
叫号;
为顾客服务;
}
}
}coend
请添加必要的信号量和P、V(或wait()、signal())操作实现上述过程的互斥和同步。要求写出完整的过程,说明信号量的含义并赋初值。
解析:在这个过程中,顾客到达银行后,需要看是否有空座位,wait(empty)取号服务需要互斥的访问,获得服务之后相应的要释放座位,营业员在有顾客之后才能够进行服务,由于营业员只有一个因此不用互斥的叫号。
semaphore seets=10; //表示空余座位数量的资源信号量,初值为10
semaphore mutex=1; //互斥信号量,初值为1,用于实现对取号机的互斥访问
semaphore custom=0; //表示顾客数量的资源信号量,初值为0 cobegin {
process 顾客i
{
P(seets);
P(mutex);
从取号机获得一个号码;
V(mutex);
V(custom);
等待叫号;
V(seets);
获得服务;
}
process 营业员
{
while(TRUE)
{
P(custom);
叫号;
为顾客服务;
}
}
2000-南京大学
桌上有1空盘,允许存放1个水果。爸爸向盘中放苹果,也可以向盘中放桔子。儿子专等吃盘中的桔子,女儿专等吃盘中的苹果。规定当盘空时一次只能放1个水果供吃者取用。
请用wait( )、signal( )原语实现爸爸、儿子、女儿三个并发进程的同步。
解析:可以将上述的问题抽象为生产者消费者模型,其中爸爸是生产者,而对于儿子和女儿来说就是消费者了,因此可以描述成如下图所示的场景:
解:设三个信号量:
plate --- 盘子是否为空,初值为1;
orange --- 盘中是否有桔子,初值为0;
apple --- 盘中是否有苹果,初值为0;
semaphore plate = 1;// 作为盘子的互斥访问信号量
semaphore orange = 0;// 作为橘子信号量
semaphore apple = 0;// 作为苹果信号量
void father()
{
while(true)
{
wait(plate);
// 放一种水果
if(fruit==orange)
signal(orange);
else
signal(apple);
}
}
void son()
{
while(true)
{
wait(orange);
// 吃水果
signal(plate);
}
}
void daughter()
{
while(true)
{
wait(apple);
// 吃水果
signal(plate);
}
}
经典例题
如图所示,有多个PUT操作同时向BUFF1放数据,有一个MOVE操作不断地将BUFF1的数据移到BUFF2,有多个GET操作不断地从BUFF2中将数据取走。BUFF1的容量为m,BUFF2的容量是n,PUT、MOVE、GET每次操作一个数据,在操作的过程中要保证数据不丢失。试用P、V原语协调PUT、MOVE的操作,并说明每个信号量的含义和初值。
【解析】这里存在两个一般意义的“生产者—消费者”问题,PUT(生产者)与MOVE(消费者)之间,需要设置三个信号量;MOVE(生产者)与GET(消费者)之间,需要设置三个信号量。PUT进程套用生产者进程即可,MOVE进程只有在Buff1有新数据且Buff2有空闲区的时候才移动数据,GET进程套用消费者进程即可。
答案:设置6个信号量full1、empty1、mutex1、full2、empty2、mutex2,它们的含义和初值如下:
- full1表示Buff1是否有数据,初值为0;
- empty1表示Buff1有空间,初值为m;
- mutex1表示Buff1是否可操作,初值为1;
- full2表示Buff2是否有数据,初值为0;
- empty2表示Buff2有空间,初值为n;
- mutex2表示Buff2是否可操作,初值为1;
semaphore empty1 = m;// 作为确定buffer1是否有位置
semaphore empty2 = n;// 作为确定buffer2是否有位置
semaphore full1 = 0;// 作为put->move的同步信号量
semaphore full2 = 0;// 作为move->get的同步信号量
semaphore mutex1 = 1;// 作为buffer1的互斥信号量
semaphore mutex2 = 1;// 作为buffer2的互斥信号量
void put()
{
while(true)
{
wait(empty1);
wait(mutex1);
// put
signal(mutex1);
signal(full1);
}
}
void move()
{
while(true)
{
wait(full1);
wait(empty2);
wait(mutex1);
wait(mutex2);
// move
signal(mutex1);
signal(mutex2);
signal(empty1);
signal(full2);
}
}
void get()
{
while(true)
{
wait(full2);
wait(mutex2);
// get
signal(mutex3);
signal(empty2);
}
}
【北京航天航空大学2001】
面包店有很多面包,由n个销售人员推销。每个顾客进店后先取一个号,并且等待叫号。当一个销售人员空闲下来时,就叫下一个号。试设计一个使销售人员和顾客同步的算法。
semaphore mutex=1, empty=∞, full=0;
//mutex:对顾客队列(缓冲区)进行互斥操作的信号量
//empty:缓冲区的空闲容量(队列中的还能容纳的顾客数)。
//full:缓冲区已占容量(队列中的顾客数)
void consumer()
{
while(true)
{
wait(empty);
wait(mutex);
// 取号
signal(mutex);
signal(full);
}
}
void producer()
{
while(true)
{
wait(full);
wait(mutex);
// 服务
signal(mutex);
signal(empty);
}
}