用多线程同步方法解决哲学家就餐问题报告剖析.docx
- 文档编号:23590501
- 上传时间:2023-05-18
- 格式:DOCX
- 页数:16
- 大小:85.87KB
用多线程同步方法解决哲学家就餐问题报告剖析.docx
《用多线程同步方法解决哲学家就餐问题报告剖析.docx》由会员分享,可在线阅读,更多相关《用多线程同步方法解决哲学家就餐问题报告剖析.docx(16页珍藏版)》请在冰豆网上搜索。
用多线程同步方法解决哲学家就餐问题报告剖析
课程设计报告书
课程名称:
计算机操作系统
题目:
用多线程同步方法解决哲学家就餐问题
系名:
专业班级:
姓名:
学号:
指导教师:
2016年6月24日
武汉华夏理工学院信息工程系
课程设计任务书
课程名称:
操作系统原理课程设计指导教师:
班级名称:
开课系、教研室:
自动化与计算机
一、课程设计目的与任务
操作系统课程设计是《操作系统原理》课程的后续实践课程,旨在通过一周的实践训练,加深学生对理论课程中操作系统概念,原理和方法的理解,加强学生综合运用操作系统原理、Linux系统、C语言程序设计技术进行实际问题处理的能力,进一步提高学生进行分析问题和解决问题的能力,包含系统分析、系统设计、系统实现和系统测试的能力。
学生将在指导老师的指导下,完成从需求分析,系统设计,编码到测试的全过程。
二、课程设计的内容与基本要求
1、课程设计题目
用多线程同步方法解决哲学家就餐问题
2、课程设计内容
本课程设计要求在Linux操作系统,GCC编译环境下开发。
用c/c++语言在Linux操作系统环境下,通过研究Linux的线程机制和信号量实现哲学家就餐问题的并发控制。
为避免死锁,可采用只许4个哲学家入席且桌上有5支筷子的办法。
几把椅子可用连续存储单元。
1每个哲学家取得一双筷子开始用餐后,即时显示“Dining…”和该哲学家的标识符以及餐桌上有几位哲学家及其所坐的位置。
2设定共有10个哲学家需用餐。
每位用餐耗时10秒钟以上。
3多个哲学家须共享操作函数代码。
提示:
1有界缓冲区/连续存储区可用数组实现。
2编译命令可用:
gcc-lpthread-o 目标文件名 源文件名
3多线程编程方法参见电子文档。
3、设计报告撰写格式要求:
1设计题目与要求2设计思想
3系统结构4数据结构的说明和模块的算法流程图
5使用说明书(即用户手册):
内容包含如何登录、退出、读、写等操作说明
6运行结果和结果分析(其中包括实验的检查结果、程序的运行情况)
7自我评价与总结
8附录:
程序清单,注意加注释(包括关键字、方法、变量等),在每个模块前加注释;
三、课程设计步骤及时间进度和场地安排
本课程设计将安排在第18周,现代教育技术中心。
具体安排如下:
时间
设计内容
第一天
下发任务书,学生查阅资料
第二天
系统设计和原型开发
第三天-第四天
系统功能实现、系统调试、测试、打包和验收
第五天
整理报告
课程设计集中时间安排:
周次
星期一
星期二
星期三
星期四
第18周
第1-2节
第3-4节
第3-4节
第3-6节
地点
现教
现教
现教
现教
四、课程设计考核及评分标准
课程设计考核将综合考虑学生的系统设计方案、运行结果、课程设计报告书的质量、态度、考勤、答辩情况等各因素。
具体评分标准如下:
(1)设计方案正确,具有可行性、创新性;30分
(2)系统开发效果较好;20分
(3)设计报告规范、课程设计报告质量高、参考文献充分20分
(4)课程设计答辩时,问题回答正确;20分
(5)态度认真、刻苦钻研、遵守纪律;10分
按上述五项分别记分后求和,总分按五级制记载最后成绩。
优秀(100~90分),良好(80~89分),中等(70~79分),及格(60~69分),不及格(0~59分)
一、设计题目:
用多线程同步方法解决哲学家就餐问题
二、设计思想:
1、为每个哲学家产生一个线程,设计正确的同步算法
2、每个哲学家取得一双筷子开始用餐后,即时显示“Dining…”和该哲学家的自定义标识符以及餐桌上所有几位哲学家标识符及其所坐的位置。
3、设定共有10个哲学家需用餐。
每位用餐耗时10秒钟以上。
4、多个哲学家须共享操作函数代码。
三、系统结构
四、主要数据结构的说明和模块的算法流程图:
1、创建函数pthread_create声明如下:
#include
Intpthread_create(pthread_t*thread,constpthread_attr_t*attr,void*(*start_routine)(void*),void*arg);
2、等待其它线程结束函数pthread_join声明如下:
#include
intpthread_join(pthread_tthread,void**retval);
3、信号量的数据类型为结构sem_t,它本质上是一个长整型的数。
初始化信号量函数sem_init声明如下:
#include
sem_init(sem_t*sem,intpshared,unsignedintvalue);
4、增加信号量值函数sem_post声明如下:
#include
intsem_post(sem_t*sem);
5、减少信号量值函数sem_wait声明如下
#include
intsem_wait(sem_t*sem);
主要数据结构声明:
1、#defineNUMBERS10//将哲学家人数NUMBERS定义为10
2、sem_tchopstics[NUMBERS]//定义5只筷子的互斥信号量chopstics
3、sem_troom//定义避免死锁的同步信号量room
线程共享函数伪代码:
void*Share(inti)
{
think();
p(room);//请求入席进餐
p(chopstick[setnumber]);//请求左手边的筷子
p(chopstick[setnumber+1]);//请求右手边的筷子
eat();
v(chopstick[setnumber]);//释放左手边的筷子
v(chopstick[setnumber+1]));//释放右手边的筷子
v(room);//退出席位释放信号量chairs
}
五、使用说明:
打开虚拟机,进入linux系统。
应用程序—终端—输入gcc–lpthread–oa.a.c—编码成功后,输入./a,得到所需结果。
六、运行结果和结果分析:
如图1、2所示:
图1
图2
[syh@localhost~]$gcc-lpthread-oaa.c
[syh@localhost~]$./a
哲学家1坐上了位置1
哲学家1拿到左侧筷子1
哲学家1拿到右侧筷子2
哲学家1坐在1椅子上吃饭
dining……
***************
哲学家1坐在椅子1上
————————————
哲学家2坐上了位置2
哲学家3坐上了位置3
哲学家3拿到左侧筷子3
哲学家3拿到右侧筷子4
哲学家3坐在3椅子上吃饭
dining……
***************
哲学家1坐在椅子1上
哲学家2坐在椅子2上
哲学家3坐在椅子3上
————————————
哲学家4坐上了位置4
哲学家1吃饱了放下筷子1和2
哲学家1离开了位置1走到一边画圈圈
哲学家3吃饱了放下筷子3和4
哲学家3离开了位置3走到一边画圈圈
哲学家2拿到左侧筷子2
哲学家2拿到右侧筷子3
哲学家2坐在2椅子上吃饭
dining……
***************
哲学家2坐在椅子2上
————————————
哲学家5坐上了位置1
哲学家5拿到左侧筷子1
哲学家4拿到左侧筷子4
哲学家4拿到右侧筷子5
哲学家4坐在4椅子上吃饭
dining……
***************
哲学家5坐在椅子1上
哲学家2坐在椅子2上
————————————
哲学家2吃饱了放下筷子2和3
哲学家4吃饱了放下筷子4和5
哲学家4离开了位置4走到一边画圈圈
哲学家5拿到右侧筷子2
哲学家5坐在1椅子上吃饭
dining……
***************
哲学家5坐在椅子1上
哲学家2坐在椅子2上
————————————
哲学家6坐上了位置3
哲学家6拿到左侧筷子3
哲学家6拿到右侧筷子4
哲学家6坐在3椅子上吃饭
dining……
***************
哲学家5坐在椅子1上
哲学家2坐在椅子2上
哲学家6坐在椅子3上
————————————
哲学家2离开了位置2走到一边画圈圈
哲学家8坐上了位置2
哲学家9坐上了位置4
哲学家5吃饱了放下筷子1和2
哲学家5离开了位置1走到一边画圈圈
哲学家6吃饱了放下筷子3和4
哲学家6离开了位置3走到一边画圈圈
哲学家8拿到左侧筷子2
哲学家8拿到右侧筷子3
哲学家8坐在2椅子上吃饭
dining……
***************
哲学家8坐在椅子2上
————————————
哲学家7坐上了位置1
哲学家7拿到左侧筷子1
哲学家9拿到左侧筷子4
哲学家9拿到右侧筷子5
哲学家9坐在4椅子上吃饭
dining……
***************
哲学家7坐在椅子1上
哲学家8坐在椅子2上
————————————
哲学家8吃饱了放下筷子2和3
哲学家7拿到右侧筷子2
哲学家7坐在1椅子上吃饭
dining……
***************
哲学家7坐在椅子1上
哲学家8坐在椅子2上
————————————
哲学家9吃饱了放下筷子4和5
哲学家9离开了位置4走到一边画圈圈
哲学家8离开了位置2走到一边画圈圈
哲学家10坐上了位置3
哲学家10拿到左侧筷子3
哲学家10拿到右侧筷子4
哲学家10坐在3椅子上吃饭
dining……
***************
哲学家7坐在椅子1上
哲学家10坐在椅子3上
————————————
哲学家7吃饱了放下筷子1和2
哲学家7离开了位置1走到一边画圈圈
哲学家10吃饱了放下筷子3和4
哲学家10离开了位置3走到一边画圈圈
七、测试过程及结果分析:
各个哲学家(线程)完全独立自主运作,达到了预期的目标,拿筷子自然无冲突,吃饭也能正常运行,全程序没有一个哲学家饿死(线程不执行),或者是有哲学家在座位上却吃不到饭(死锁)的问题。
所有的哲学家都可以去画圈圈。
八、心得体会:
虽然这次课程设计用了一星期,但是通过查阅资料,还是有了很大的收获,,使我对操作系统的基本知识有了进一步的提高,并在实践中对各种概念有了进一步的深化。
初看别人的编程,根本就不知道写的是什么。
只知道不停的运行,却一直得不到结果,坐着干着急。
后来,慢慢地从一点一滴的学习中,能够将程序读懂了,这就是最大的进步。
通过这次课程设计,我确实学到了很多东西,这些学到的东西可以使我受益终生。
除了知识技术上的东西,我更锻炼了自己的快速学习能力。
总的来说,这次的课程设计的收获比较大,对LINUX的运用以及编程都更进了一步。
一个看似小程序,却包含了很多辛劳,没有扎实的理论基础和熟练地操作是很难在短时间内完成作品的。
九、附录:
#include
#include
#include
#include
#defineNUMBERS10//设置哲学家数目
sem_tchopstics[5];//设置筷子数目
sem_troom;//设置房屋信号灯
sem_tmutex;//设置互斥信号灯
sem_tyourenmutex;//设置有人互斥信号灯
intyouren[5]={0,0,0,0,0};//设置是人变量
intchairs[4]={1,2,3,4};//设置椅子
inti,j;//设置2循环用变量
void*Share(intthreadid);//定义哲学家函数
//主函数
intmain(){
interror;//设定错误变量
pthread_tthreads[NUMBERS];//设置线程数
for(i=0;i<5;i++)//循环设置筷子信号灯{
sem_init(&chopstics[i],0,1);}
sem_init(&room,0,4);//设置房间信号灯
sem_init(&mutex,0,1);//设置互斥信号灯
for(i=1;i error=pthread_create(&threads[i],NULL,(void*)Share,(void*)i); if(error)//判断是否产生哲学家{ printf("\nERROR: 哲学家没有被创建\n");}} for(i=1;i pthread_join(threads[i],NULL);}} //哲学家函数 void*Share(intthreadid){ inti=threadid;//读取哲学家编号 intsetnumber=1;//设置座位量 sem_wait(&room);//room信号-1 for(setnumber=1;setnumber<=4;setnumber++)//检测哪个位置空出来{ if(youren[setnumber]==0){ youren[setnumber]=i;//让哲学家去坐座位,并修改有人编号为哲学家编号 printf("哲学家%d坐上了椅子%d\n",i,setnumber); sem_post(&yourenmutex);//解除有人互斥 break;}} sem_wait(&chopstics[setnumber]);//拿起左边筷子信号灯 printf("哲学家%d拿到左侧筷子%d\n",i,setnumber); sem_wait(&chopstics[setnumber+1]);//拿起右边筷子信号灯 printf("哲学家%d拿到右侧筷子%d\n",i,setnumber+1); sem_wait(&mutex);//互斥 printf("哲学家%d坐在%d椅子上吃饭\n",i,chairs[setnumber-1]); printf("dining……\n"); printf("***************\n"); for(j=0;j<4;j++){ if(youren[j]! =0) printf("哲学家%d坐在椅子%d上\n",youren[j],chairs[j-1]);} printf("————————————\n"); sem_post(&mutex);//解除互斥 sleep (1);//吃十秒 sem_post(&chopstics[setnumber]);//放下左边筷子信号灯 sem_post(&chopstics[setnumber+1]);//放下右边筷子信号灯 printf("哲学家%d吃饱了放下筷子%d和%d\n",i,setnumber,setnumber+1); sem_wait(&yourenmutex);//有人互斥 youren[setnumber]=0; printf("\n哲学家%d离开了椅子%d走到一边画圈圈\n\n",i,setnumber); sem_post(&yourenmutex);//解除有人互斥 sem_post(&room);//room信号灯+1 } 设计过程中质疑(或答辩)记载: 1、怎样防止死锁? 针对每个哲学家,通过共享操作函数代码,分别建立5个线程,以实现同步哲学家就餐,而申请进入餐厅的哲学家进入room的等待队列,根据FIFO的原则,总会进入到餐厅就餐,因此不会出现饿死和死锁的现象 2、哲学家左边的筷子具体是什么? 根据座位的编号来设置相应的筷子编号,例如1号座位对应的左边和右边的筷子是1和2,3号座位对应的筷子是2和3,按照顺序以此类推。 3、#include #include #include 指导教师评语: 签名: 年月日
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 多线程 同步 方法 解决 哲学家 就餐 问题 报告 剖析