哲学家就餐问题

2026/4/25 7:07:22

(2013-2014学年

第二学期)

重庆理工大学研究生课程论文

课程论文题目:

基于 ucos-ii操作系统解决哲学家就餐问题

(Problem of Philosophers’ Dining)

课程名称 课程类别 任课教师 所在学院 学科专业 姓学

名 号 嵌入式系统实验与实践

□学位课 □非学位课

万文略 电子学院 仪器仪表工程

王小辉

51307260101 2014年6月27日 提交日期 注意事项: 1、以上各项由研究生认真填写; 2、研究生课程论文应符合一般学术规范,具有一定学术价值,严禁网上下载或抄袭;凡检查或抽查不合格者,一律取消该门课程成绩和学分,并按有关规 定追究相关人员责任; 3、论文得分由批阅教师填写(见封底),并签字确认;批阅教师应根据作业质 量客观、公正的在文后签写批阅意见; 4、原则上要求所有课程论文均须用A4纸打印,加装本封面封底,左侧装订; 5、课程论文由各学院(部)统一保存,以备查用。 4、卷纸不够写,可另附纸。

基于ucos-ii的哲学家就餐解决方案

摘要:针对经典的哲学家进餐问题,对多任务同步运行进行了研究。介绍了基于ucos-ii的多任务程序设计和任务间的通信机制,列举了可行的实现方法。并给出了最后的运行结果,使得哲学家能够正常进餐,不被饿死。 关键词:互斥 同步 多任务 任务间通信 顺序

一、问题陈列

哲学家进餐问题是荷兰学者Dijkstra 提出的经典问题之一,它是一个信号量机制问题的应用,在操作系统文化史上具有非常重要的地位。假设有5个哲学家,他们花费一生中的时光思考和吃饭。这些哲学家共用一个圆桌,每个哲学家都有一把椅子。在桌子中央是一碗通心面,在桌子上放着5只筷子。哲学家感到饥饿时,并试图拿起与他相近的两只筷子(他与邻近左、右之间的筷子)吃饭。

要求:

①哲学家一次只能拿一只筷子,且必须拥有两只筷子才能吃饭。 ②如果筷子已被别人拿走,必须等到别人吃完放下才能拿到筷子。 ③每个哲学家在没拿到第二只筷子时,不会放弃手中已拿到的一只筷子。 ④假定哲学家每次吃饭的时间长度为单位1,吃完一次后则放下两只筷子。如果等待l0个单位时间长度之后,哲学家仍没有得到筷子吃饭,则被饿死。

设计一种方法使得任何一个哲学家都不被饿死。

二、问题分析

对问题分析可知,目前问题的瓶颈在于:死锁。 死锁的发生必须满足以下四个必要条件:

①互斥:至少有一个资源每次只能被一个进程使用,即非共享模式。这里指每只筷子只能被一个哲学家持有。

②占有并等待。一个进程因请求资源而阻塞时,对已获得的资源保持不放。这里指哲学家在没拿到第二只筷子时,不会放弃手中已拿到的一只筷子。

③不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。这里指哲学家不能去抢别人的筷子。

④循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。 这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

在系统设计、进程调度等方面注意避免让这四个必要条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态的情况下占用资源。即,对资源的分配要给予合理的规划。

三、方案设计

要避免死锁,最好的方法是复制原本需要互斥访问的资源,这样每个进程都拥有一个资源的私有副本。每个进程访问自己的副本,从而可以避免使用锁。这种不使用锁的方法,从根本上消除了死锁存在的可能,并进一步提高了可扩展性和该组件的可组装型。即本问题可以通过增加筷子数而避免死锁,但与解题要求不符,所以另寻他法。

既然资源无法被复制,按一定的顺序获取资源锁,也可以避免死锁。这里我们可以通过设置各任务挂起顺序而避免死锁,也可以通过为每个资源锁分配一个唯一的整数,再允许用户比较各资源锁以确定其先后顺序。

对于哲学家晚餐的问题,我是选取的最后这种方法,即为每个任务分配了唯一的门槛整数,是它就运行相应程序,不是就得释放资源等待时机,为其他任务运行腾资源。

由于问题中有五只筷子,也就是说两不相邻的哲学家可以同时吃,所以出于资源充分利用原则,我让一个任务运行处理两个哲学家的吃饭问题,当然这两个哲学家必须是不相邻的。其实建立三个这样的任务,就能保证哲学家不饿死(任务一:处理哲学家1、3;任务二:处理哲学家2、4;任务三:处理哲学家3、5;)。但出于公平考虑,我建立了五个这样任务,既任务一:处理哲学家1、3;任务二:处理哲学家2、4;任务三:处理哲学家3、5;任务四:处理哲学家4、1;任务二:处理哲学家5、2,这样一个循环下来,每人吃饭2次,且时间间隔也一致,更具人性化。

四、源程序代码

#include #include #include #ifdef __GNUC__ /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf set to 'Yes') calls __io_putchar() */

#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else

#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif /* __GNUC__ */

OS_STK philosopher1and3_Stack[100]; //建立哲学家任务块堆栈 OS_STK philosopher2and4_Stack[100]; //建立哲学家任务块堆栈 OS_STK philosopher3and5_Stack[100]; //建立哲学家任务块堆栈 OS_STK philosopher4and1_Stack[100]; //建立哲学家任务块堆栈 OS_STK philosopher5and2_Stack[100]; //建立哲学家任务块堆栈 OS_STK conduct_stack[100]; //建立门槛设置任务块堆栈 OS_EVENT *stick[5]; //五个筷子事件 #define PHILOSOPHER1 1 // 哲学家编号 #define PHILOSOPHER2 2 //哲学家编号 #define PHILOSOPHER3 3 //哲学家编号 #define PHILOSOPHER4 4 //哲学家编号 #define PHILOSOPHER5 5 //哲学家编号 const INT8U philosopher[5]={8,9,10,11,12}; int swich=0; // 门槛整数 int end_flag=5; //门槛整数

void task_philosopher1and3(void); //定义哲学家任务 void task_philosopher2and4(void); //定义哲学家任务 void task_philosopher3and5(void); //定义哲学家任务 void task_philosopher4and1(void); //定义哲学家任务 void task_philosopher5and2(void); //定义哲学家任务 void task_conduct(void); //定义门槛设置任务 void think(int i); //定义哲学家思考函数 void Take_fork(int i); //定义哲学家拿筷子函数 void Eat(int i); //定义哲学家吃饭函数 void Put_fork(int i); //定义哲学家放筷子函数 static void systick_init(void); //定义系统时钟函数 int main() {

int i;

INT8U err;

USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO |


哲学家就餐问题.doc 将本文的Word文档下载到电脑
搜索更多关于: 哲学家就餐问题 的文档
相关推荐
相关阅读
× 游客快捷下载通道(下载后可以自由复制和排版)

下载本文档需要支付 10

支付方式:

开通VIP包月会员 特价:29元/月

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:xuecool-com QQ:370150219