- 1、本文档共3页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
哲学家就餐实验报告.pdf
线程解决哲学家就餐问题实验报告
一、 实验题目
哲学家就餐问题是一种典型的同步问题,它是由Dijkstra 提出并解决的。该问题描述如
下:有五个 学家,他们的生活方式是交替的进行思考和进餐。 学家们共用一张圆桌,如
图所示:
设五个 学家分别编号为A ,B ,C,D ,E ,桌子上放着五把筷子,筷子分别编号为0,1,
2 ,3,4 ,桌子中央有一盘饭菜。五个 学家都很有礼貌,都要等同时拿到身旁的两只筷子
才进餐,不然就只是等着继续思考,而且吃了一口之后又马上放下拿起的两根筷子,继续思
考。
由于筷子数目有限,不能让五个哲学家同时进餐,而且甚至只能让其中的少数 学家进
餐,其他的哲学家只能轮流享用,这非常类似多线程之间的同步互斥问题,所以采用windows
的多线程及一些API 函数实现了对这个经典算法的模拟。
二、 主要算法及函数的使用
1)解法一:
每根筷子设一个信号量 CRITICAL_SECTION 类型的变量,用一个数组保存
CRITICAL_SECTION Tropstick[5]; ,然后为每个 学家开一个子线程,用 API 函数
EnterCriticalSection ()来实现临界区的互斥,这里用五根筷子的信号量来作为互斥的信号
量,然后在屏幕打印 学家拿起筷子和就餐的语句为临界区语句。每个 学家线程的临界区
语句之后 (即打印了了就餐的语句后),用LeaveCriticalSection()函数释放信号量 (即该哲学
家拿起的两根筷子),哲学家拿起筷子、就餐、放下筷子的动作都用打印屏幕的方法来显示
模拟。五个 学家线程的对应的函数基本相同,只是用到的信号量不同还有打印屏幕的语句
不同而已。
主线程主要有几个操作,一是初始化这五根筷子对应的信号量,二是启动这五个 学家
线程。然后用一个循环来查询一个计数值,每当有一个哲学家就餐一次就自增一,然后达到
一定数量后就终 主线程,子线程原来是用一个死循环来不断模拟哲学家就餐的,由于主线
程已经终 ,所以子线程也随之结束。
这个算法出现了一个比较奇怪的现象,本来每个筷子对应一个信号量,然后每个 学家
那每一根筷子都对应一个进入临界区的函数来阻塞等待信号量的激活。信号量激活了线程,
1
停 了阻塞,然后就打印该 学家获得了该根筷子的语句,结果发现程序运到一定时刻后会
出现同一根哲学家连续两次获取了同一根筷子,或者连续两次放下了同一根筷子,即改出问
题的线程的这个获取筷子或者放下筷子的语句被意外地连续执行了两次,而其后的语句是还
没执行的,看起来就像执行了该语句后跳过了后面的语句 再次进入临界区马上又多执行了
一次该语句,而且无论怎样调整获取筷子的顺序都会出现这个现象,至今无法解决。遂我产
生了用其他方法来重新实现一次这个 学家就餐问题算法的打算,即下面所说的两种解法,
下面两种解法都很顺利模拟了这个问题,而且没有出现这个奇怪的现象。
2 )解法二:
每根筷子用一个句柄HANDLE 表示,也是用一个数组保存HANDLE Tropstick[5];,然
后临界区的互斥改用了::WaitForSingleObj ect(Tropstick[0],INFINITE); 的方法来实现,当
Tropstick[0]句柄没有改变时线程就阻塞在这里,当这个句柄一被改变,马上终 阻塞,继续
执行下面的语句,相当于进入了临界区。然后离开临界区时,放下筷子的动作
用::ReleaseSemaphore(Tropstick[1],1,NULL);模拟,以激活其他需要该根筷子的 学家线程。
主线程首先是初始化五个句柄,用Tropstick[0]=::CreateSemaphore(NULL,0,1,Tropstick
1); 的语句实现。然后启动五个哲学家线程,但由于 WaitForSingleObj ect ()函数的特点,
五个哲学家线程都会因为筷子的句柄没有变动而全部阻塞在等筷子的语句上。所以主线程除
了初始化句柄和启动子线程外,还加了五个::ReleaseSemaphore(Tropstick[0],1,NULL);语句来
分别激活五根筷子的句柄,这样程序便能正常运行了。
3)解法三:
由于对Windows 的API 函数的机理不太了解,而且 出现了解法一的奇怪问题
文档评论(0)