IPC习题(上)

IPC习题

1 仓库问题

有一个仓库,可以存放 A 和 B 两种产品,仓库的存储空间足够大,但要求: (1)一次只能存入一种产品(A 或 B); (2)-N < (A 产品数量-B 产品数量) < M。 其中,N 和 M 是正整数。试用“存放 A”和“存放 B”以及 P、V 操作描述产品 A 与 产品 B 的入库过程。

分析:

A - B < M
B - A < N
所以在仓库只存放A时,A最大可取M-1。同理只存放B时,B最大为N-1。

伪代码

Semaphore mutex = 1;   //互斥信号量
Semaphore a = M-1 ;   //存放A的资源信号量,初值为M-1
Semaphore b = N-1;      //存放B的资源信号量,初值为N-1
void StorageA:
{
    while(true)
	{
   		GetA()P(a); 
   		P(mutex); 
		PutA()V(mutex);  
        V(b);
    }  
} 
void StorageB:
{ 
    while(true)
    { 
        GetB()P(b);
        P(mutex);
        PutB()V(mutex);
        V(a);
    }
}

2.水果问题

桌子上有一只盘子,最多可容纳两个水果,每次只能放入或取出一个水果。爸爸专向盘 子放苹果(apple),妈妈专向盘子中放桔子(orange);两个儿子专等吃盘子中的桔子, 两个女儿专等吃盘子中的苹果。请用 P、V 操作来实现爸爸、妈妈、儿子、女儿之间的 同步与互斥关系。

分析:

本题需要设置4个信号量,其中empty表示还可以向盘中放几个水果,初始值为2。apple对应已放入的苹果,orange代表已放入的桔子,初始值都为0。mutex用来实现对盘子的互斥访问(放或取),初始值为1。

伪代码:

void father(){
	while(true){
		P(empty);
		P(mutex);
		向盘中放苹果();
		V(mutex);
		V(apple);	}
}

void mother(){
	while(true){
		P(empty);
		P(mutex);
		向盘中放入桔子();
		V(mutex);
		V(orange);
}

void son(){
	while(true){
		P(orange);
		P(mutex);
		取出桔子();
		V(mutex);
		V(empty);
		吃桔子();
	}
}

void daughter(){
	while(true){
		P(apple);
		P(mutex);
		取出苹果();
		V(mutex);
		V(empty);
		吃苹果();
	}
}

3.理发师问题

有一个理发师,一把理发椅和 N 把供等候理发的顾客坐的椅子。如果没有顾客,则理发 师便在理发师椅子上睡觉;当一个顾客到来时,必须唤醒理发师进行理发;如果理发师正在理发时又有顾客来到,则如果有空椅子可坐,他就坐下来等,如果没有空椅子,他就离开。为理发师和顾客各编一段程序(伪代码)描述他们的行为,要求不能带有竞争条件。

分析

本题应该设置三个信号量,customers代表等待服务的顾客,初始值为0、barbers代表等待顾客的理发师,初始值为0、mutex用来实现互斥访问,初始值为1。

伪代码

#define CHAIRS 5               /* # chairs for waiting customers */
semaphore customers = 0;       /* # of customers waiting for service */
semaphore barbers = 0;         /* # of barbers waiting for customers */
semaphore mutex = 1;           /* for mutual exclusion */
int waiting = 0;               /* customers are waiting (not being cut) */

void barber(void)
{
    while (true) {
        P(customers);          /* go to sleep if # of customers is 0 */
        P(mutex);              /* acquire access to 'waiting' */
        waiting = waiting − 1; /* decrement count of waiting customers */
        V(barbers);            /* one barber is now ready to cut hair */
        V(mutex);              /* release 'waiting' */
        cut_hair();            /* cut hair (outside critical region) */
    }
}

void customer(void)
{
    P(mutex);                  /* enter critical region */
    if (waiting < CHAIRS) {    /* if there are no free chairs, leave */
        waiting = waiting + 1; /* increment count of waiting customers */
        V(customers);          /* wake up barber if necessary */
        V(mutex);              /* release access to 'waiting' */
        P(barbers);            /* go to sleep if # of free barbers is 0 */
        get_haircut();         /* be seated and be serviced */
    } else {
        V(mutex);              /* shop is full; do not wait */
    }
}

4.吸烟者问题

吸烟者问题。三个吸烟者在一间房间内,还有一个香烟供应者。为了制造并抽掉香烟, 每个吸烟者需要三样东西:烟草、纸和火柴。供应者有丰富的货物提供。三个吸烟者中, 第一个有自己的烟草,第二个有自己的纸,第三个有自己的火柴。供应者将两样东西放在桌子上,允许一个吸烟者进行对健康不利的吸烟。当吸烟者完成吸烟后唤醒供应者, 供应者再放两样东西(随机地)在桌面上,然后唤醒另一个吸烟者。试为吸烟者和供应者编写程序解决问题。

伪代码

semaphore mutex = 1;
semaphore s1 = 0;
semaphore s2 = 0;
semaphore s3 = 0;
bool flag1 = true, flag2 = true; flag3 = true;

void provider(){
	while(true){
		P(mutex);
		取两样香烟原料并用flagi标记();
		if(flag2 && flag3){
			V(s1);
		}else if(flag1 && flag2){
			V(s2);
		}else{
			V(s3);
		}
	}
}
void smoker1(){
	while(true){
		P(s1);
		取原料做香烟();
		V(mutex);
		吸烟();
	}
}
void smoker2(){
	while(true){
		P(s2);
		取原料做香烟();
		V(mutex);
		吸烟();
	}
}
void smoker3(){
	while(true){
		P(s3);
		取原料做香烟();
		V(mutex);
		吸烟();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值