好 那我们来看一下
哲学家就餐问题一个实现
在lab7中我们给大家提供了
基于信号量的
哲学家就餐问题的实现
在这里面 我们需要大家去实现
基于管程和条件变量的
哲学家就餐问题
既然是基于管程
我们就需要考虑
怎么对管程进行定义
和完成相应的初始化
这是第一步工作
可以看到
对于哲学家就餐问题呢
我们和前面的讲解是一样的
他会有一个哲学家一个状态
包括了思考 饥饿 吃饭
这三个状态
同时我们还定义了
跟这五个哲学家相关的条件变量
这个self一共有5个
那他的初始化代码在哪呢
一开始的时候
我们会把哲学家
都初始化为thinking状态
这就是他的初始化的工作
这就是管程初始化一个
大致一个表述
我们会产生
五个哲学家的内核线程
来模拟哲学家的行为
那这个内核线程呢
他干事情是什么呢
他实际上是一个循环
在这个循环里面
完成thinking然后感觉饥饿
然后就尝试着去取两个筷子
左手和右手的筷子
当然这个取筷子呢
实际上是调的是我们说
管程里面的一些操作
这个操作需要完成一定的
同步互斥的一些要求
然后拿到筷子之后他会eating
如果拿不到呢
很自然 他就会去睡眠
好eating完之后呢
他会把筷子再放回去
这就是他大致一个过程
需要注意的是 在这里面
取筷子和放筷子呢
都是管程的操作
那我们看看 管程里面
怎么来实现这些操作
在管程里面
我们提供了三个函数
一个是取筷子 一个是放筷子
还有一个是辅助取筷子
和放筷子的一个Test函数
那么这个函数实现
和我们用信号量方式实现呢
有很多类似地方 但是有不同
需要注意 在哪呢
关键两个地方 一个Wait_cv
一个是Signal_cv
这就是调用的信号量的
等待或唤醒换作
我们简单看一下
第一个是pickup 就是拿筷子
那他首先会把他自身的状态
置成hungry 表示我现在饥饿了
然后执行test
看我自身的左侧邻居和右侧邻居
是否是不处于eating状态
如果不处于eating状态
也就意味着他可以拿到筷子
所以他会执行一个Signal_cv
来把自身设置成一个
可以去吃的一个状态
同时 还会继续去进一步执行
但是如果说他不这样的话
那么他会执行什么呢
执行完test返回之后
如果他不是一种吃的状态
那意味着他现在无法
拿到足够的筷子
他会通过执行Wait_cv操作呢
来完成一个等待的一个过程
这是拿筷子的过程
可以看出 在拿筷子里面
有可能他拿到筷子
处于一个吃的状态
也有可能拿不到筷子
然后调用Wait_cv呢
使自身进入一个等待状态
当吃完饭之后呢
他会再执行一个putdown操作
那putdown呢
会把他的左手筷子
和右手筷子放回去
在放的过程中 还会去探测
他的左侧邻居 或者是右侧邻居
是否可以处于eating状态
如果发现他们可以处于eating状态
他就会通过执行一个Signal_cv
来把相应的邻居给唤醒
且把他们状态置成eating
这就是pickup和putdown的
大致的一个实现
那么大家基于大致的流程呢
可以去尝试在lab7中完成
基于管程和条件变量的一个
哲学家就餐问题的实现
当然这取决于
你能够正确地完成管程
和条件变量一个实现
而我们条件变量
是基于信号量来完成的
好 那通过前面的讲解呢
大家能够去了解信号量 条件变量
管程是如何实现的
以及他们之间的相互关系
还有就是基于这些机制呢
我们怎么能够去完成
相应的同步互斥的问题
比如说哲学家就餐问题
好 祝大家实验顺利