PV操作几个例题

例1
在一个盒子里,混装了数量相等的黑白围棋子。现在用自动分拣系统把黑子、白子分开,设分拣系统有二个进程P1和P2,其中P1拣白子;P2拣黑子。
注意:

  • 规定每个进程每次拣一子当一个进程在拣时,不允许另一个进程去拣。
  • 当一个进程拣了一子时,必须让另一个进程去栋。
    试写出两进程P1和P2能并发正确执行的程序。
    分析:这是一个有序进行的程序,是同步关系。需设置两个信号量s1,s2来协调他们的活动。
    设 s1=1; s2=0;
void white()
{
	while(true)
	{
		wait(s1);
		//拣白子
		signal(s2);//发消息告知机器该拣黑子了
	}
}
void black()
{
	while(true)
	{
		wait(s2);
		//拣黑子
		signal(s1);//发消息告知机器该拣白子了
	}
}

例2:有一阅览室,共有100个座位。读者进入时必须先在一种登记表上登记,该表为每一座位列一个表目,包括座号和读者姓名。读者离开时要注销掉登记内容。试用wait和signal原语描述读者进程的同步问题。

semaphore empty = 100;// 记录空座位
semaphore mutex = 1;// 作为互斥的访问登记和注销操作
void reader()
{
	while(true)
	{
		wait(empty);
		wait(mutex);
		// 此阶段为登记时期
		signal(mutex);
		// 正常阅读
		wait(mutex);
		// 离开,注销登记表
		signal(mutex);
		signal(empty);
	}

例3:在一间酒吧里有三个音乐爱好者队列,第一个音乐爱好者只有随身听,第二个只有音乐磁带,第三个只有电池,而要听音乐就必须有随身听,音乐磁带和电池这三种物品。酒吧老板一次出售这三种物品中的任意两种,当一名音乐爱好者得到这三种物品并进入听完歌曲后,酒吧老板才能再一次出售这三种物品中任意两种,于是第二名音乐爱好者得到这三种物品。并开始听歌曲,全部买卖就这样进行下去。使用P,V操作正确解决这一买卖。

semaphore s = 1;
bool flag1,flag2,flag3 = true;// 标识是否有资源
semaphore s1 = 0,s2 = 0,s3 = 0;// 作为和爱好者进行同步的信号量
void boss()
{
	while(true)
	{
		wait(s);//确认是否有顾客要买资源
		if(flag2&flag3)
			signal(s1);
		else if(flag1&flag3)
			signal(s2); 
		else
			signal(s3); 
	}
}
void hobby1()
{
	while(true)
	{
		wait(s1);
		// 购买物品听乐曲
		signal(s);// 发消息告知老板我已买好了所有物品
	}
}
void hobby2()
{
	while(true)
	{
		wait(s2);
		// 购买物品听乐曲
		signal(s);// 发消息告知老板我已买好了所有物品
	}
}
void hobby3()
{
	while(true)
	{
		wait(s3);
		// 购买物品听乐曲
		signal(s);// 发消息告知老板我已买好了所有物品
	}
  • 12
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
哲学家进餐问题可以使用信号量(Semaphore)来解决,其中PV操作是指P操作和V操作。 P操作(也称为wait操作)用于申请资源,如果资源不可用,则进程会被阻塞,直到资源可用为止。V操作(也称为signal操作)用于释放资源,使得其他进程可以继续执行。 对于四个哲学家进餐问题,可以使用四个信号量来表示每个哲学家的状态,以及一个额外的信号量来限制最多只有四个哲学家同时进餐。 下面是一个示例代码,演示了四个哲学家进餐问题的解决思路: ```python import threading # 定义信号量 forks = [threading.Semaphore(1) for _ in range(5)] eating_limit = threading.Semaphore(4) # 定义哲学家类 class Philosopher(threading.Thread): def __init__(self, index): super().__init__() self.index = index def run(self): while True: # 思考 self.think() # 进餐 self.eat() def think(self): print(f"Philosopher {self.index} is thinking.") def eat(self): # 申请资源 eating_limit.acquire() forks[self.index].acquire() forks[(self.index + 1) % 5].acquire() # 进餐 print(f"Philosopher {self.index} is eating.") # 释放资源 forks[self.index].release() forks[(self.index + 1) % 5].release() eating_limit.release() # 创建哲学家线程并启动 philosophers = [Philosopher(i) for i in range(5)] for philosopher in philosophers: philosopher.start() ``` 在上述代码中,每个哲学家都是一个线程,通过调用`think()`和`eat()`方法来进行思考和进餐。在进餐时,先申请资源(两只筷子),然后进行进餐,最后释放资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值