武汉理工大学《操作系统》课程设计题目:用多线程同步方法解决哲学家就餐问题(Dining-PhilosophersProblem)初始条件:1.操作系统:Linux2.程序设计语言:C语言3.共有5个哲学家需用餐。只许4个哲学家入席且桌上有5支筷子。要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.技术要求:1)为每个哲学家产生一个线程,设计正确的同步算法2)每个哲学家取得一双筷子开始用餐后,即时显示“Dining…”和该哲学家的自定义标识符以及餐桌上所有几位哲学家标识符及其所坐的位置。3)设定共有5个哲学家需用餐。每位用餐耗时10秒钟以上。4)多个哲学家须共享操作函数代码。2.设计说明书内容要求:1)设计题目与要求2)总的设计思想及系统平台、语言、工具等。3)数据结构与模块说明(功能与流程图)4)给出用户名、源程序名、目标程序名和源程序及其运行结果。(要注明存储各个程序及其运行结果的Linux主机IP地址和目录。)5)运行结果与运行情况(提示:(1)连续存储区可用数组实现。(2)编译命令可用:cc-lpthread-o目标文件名源文件名(3)多线程编程方法参见附件。)3.调试报告:1)调试记录2)自我评析和总结上机时间安排:18周一~五08:0-12:00指导教师签名:年月日系主任(或责任教师)签名:年月日用多线程同步方法解决哲学家就餐问题武汉理工大学《操作系统》课程设计1(Dining-PhilosophersProblem)1.设计题目与要求1.1设计题目描述:用多线程同步方法解决哲学家就餐问题(Dining-PhilosophersProblem)1.2要求:1)为每个哲学家产生一个线程,设计正确的同步算法2)每个哲学家取得一双筷子开始用餐后,即时显示“Dining…”和该哲学家的自定义标识符以及餐桌上所有几位哲学家标识符及其所坐的位置。3)设定共有5个哲学家需用餐。每位用餐耗时10秒钟以上。4)多个哲学家须共享操作函数代码。2.总体设计思想及系统平台、语言、工具2.1总体设计思想哲学家就餐问题,即共有5个哲学家绕一个圆桌做在5个位置上,他们每2个人中间有一只筷子,共5只筷子,只有当每个哲学家取得他左右两边的筷子时,哲学家才能开始就餐,其它时间,哲学家只能思考或等待筷子。为避免哲学家互相等待对方的筷子发生死锁,本次课程设计要求只许4个哲学家入席,以保证至少有一个哲学家能够进餐。本课程设计将room作为信号量,将其初始化为4,以保证只允许4个哲学家同时入席就餐,这样就能保证至少有一个哲学家可以就餐。针对每个哲学家,通过共享操作函数代码,分别建立5个线程,以实现同步哲学家就餐,而申请进入餐厅的哲学家进入room的等待队列,根据FIFO的原则,总会进入到餐厅就餐,因此不会出现饿死和死锁的现象,针对5只筷子分别设置了5个互斥信号量,以保证每只筷子每次只能被取得一次。2.2系统平台、语言及工具(1)操作系统:Linux(2)程序设计语言:C语言(3)工具:编辑工具Vi、编译器gcc武汉理工大学《操作系统》课程设计23.数据结构与模块说明线程创建函数pthread_create声明如下:#includepthread.hintpthread_create(pthread_t*thread,pthread_attr_t*attr,Void*(*start_routine)(void*),void*arg);等待其它线程结束函数pthread_join声明如下:#includepthread.hintpthread_join(pthread_tth,void*thread_return);信号量的数据类型为结构sem_t,它本质上是一个长整型的数。初始化信号量函数sem_init声明如下:#includesemaphore.hsem_init(sem_t*sem,intpshared,unsignedintvalue);增加信号量值函数sem_post声明如下:#includesemaphore.hSem_post(sem_t*sem);减少信号量值函数sem_wait声明如下#includesemaphore.hSem_wait(sem_t*sem);主要数据结构声明:#defineNUMBERS5//将哲学家人数NUMBERS定义为5sem_tchopstics[NUMBERS]//定义5只筷子的互斥信号量chopsticssem_troom//定义避免死锁的同步信号量room线程共享函数伪代码:武汉理工大学《操作系统》课程设计3void*Share(inti){think();wait(room);//请求入席进餐wait(chopstick[i]);//请求左手边的筷子wait(chopstick[(i+1)%5]);//请求右手边的筷子eat();signal(chopstick[i]);//释放左手边的筷子signal(chopstick[(i+1)%5]);//释放右手边的筷子signal(room);//退出席位释放信号量chairs}4.用户名、源程序名、目标程序名和源程序4.1用户名、源程序名、目标程序名用户名:源程序名:目标程序名:4.2源程序#includestdio.h#includeunistd.h#includepthread.h#includesemaphore.h#defineNUMBERS5sem_tchopstics[NUMBERS];sem_troom;sem_tmutex;intflag[NUMBERS]={0,0,0,0,0};intchairs[NUMBERS]={0,1,2,3,4};inti,j;void*Share(intthreadid);武汉理工大学《操作系统》课程设计4intmain(){interror;pthread_tthreads[NUMBERS];for(i=0;iNUMBERS;i++){sem_init(&chopstics[i],0,1);}sem_init(&room,0,NUMBERS-1);sem_init(&mutex,0,1);for(i=0;iNUMBERS;i++){error=pthread_create(&threads[i],NULL,(void*)Share,(void*)i);if(error){printf(ERROR:threadcreatefailed!!!);//exit(-1);}}for(i=0;iNUMBERS;i++){pthread_join(threads[i],NULL);}}void*Share(intthreadid){inti=threadid;sem_wait(&room);武汉理工大学《操作系统》课程设计5flag[i]=1;sem_wait(&chopstics[i]);printf(philosopher%dgetchopstics%d\n,i,i);sem_wait(&chopstics[(i+1)%NUMBERS]);printf(philosopher%dgetchopstics%d\n,i,(i+1)%NUMBERS);sem_wait(&mutex);printf(\n*********************************************\n);printf(Dining...\n);printf(philosopher:%d,onchairs%dandeating\n,i,chairs[i]);for(j=0;jNUMBERS;j++){if((j!=i)&&flag[j])printf(philosopher%d,onchairs%dandhungry\n,j,chairs[j]);}sleep(3);sem_post(&mutex);sem_post(&chopstics[i]);sem_post(&chopstics[(i+1)%NUMBERS]);printf(philosopher%disfullandputdownchopstics%dand%dandleft\n,i,i,(i+1)%NUMBERS);printf(*********************************************\n\n);flag[i]=0;sem_post(&room);}5.运行结果6.调试记录(1)将写好的代码进行编译,出现如下错误提示:武汉理工大学《操作系统》课程设计61.c:(.text+0x37):undefinedreferenceto`sem_init'1.c:(.text+0x6a):undefinedreferenceto`sem_init'1.c:(.text+0x86):undefinedreferenceto`sem_init'1.c:(.text+0xc8):undefinedreferenceto`pthread_create'1.c:(.text+0x108):undefinedreferenceto`pthread_join'/tmp/ccq8XD3O.o:Infunction`Share':1.c:(.text+0x13f):undefinedreferenceto`sem_wait'1.c:(.text+0x160):undefinedreferenceto`sem_wait'1.c:(.text+0x1b0):undefinedreferenceto`sem_wait'1.c:(.text+0x1f7):undefinedreferenceto`sem_wait'1.c:(.text+0x2ad):undefinedreferenceto`sem_post'1.c:(.text+0x2c0):undefinedreferenceto`sem_post'1.c:(.text+0x2f5):undefinedreferenceto`sem_post'1.c:(.text+0x35d):undefinedreferenceto`sem_post'collect2:ldreturned1exitstatus检查发现,pthread库不是Linux系统默认的库,连接时需要使用库libpthread.a,所以在使用pthread_create创建线程时,在编译中要加-lpthread参数:gcc-lpthread-o11.c(2)重新编译代码,出现如下错误提示:1.c:9:error:invalidinitializer1.c:10:error:invalidinitializer1.c:Infunction‘main’:1.c:35:warning:incompatibleimplicitdeclarationofbuilt-infunction‘exit’1.c:Infunction‘Share’:1.c:48:error:incompatibletypeswhenassigningtotype‘sem_t’fromtype‘int’1.c:71:error:expected‘;’before‘sem_post’1.c:76:error:incompatibletypeswhenassigningtotype‘sem_t’from武汉理工大学《操作系统》课程设计7type‘int’仔细查看代码,发是对信号灯初始不能在定义的时候直接初始化,改用sem_init()函数对room,mutex和flag[]进行初始化,去掉exit()函数,找到缺少‘;’的地方,添加‘;’(3)重新编译、连接、运行程序,出现如下错误提示:1.c:Infunction‘Share’:1.c:48:error:incompatibletypeswhenassigningtotype‘sem_t’fromtype‘int’1.c:76:error:incompatible