死锁问题#优选材料_第1页
死锁问题#优选材料_第2页
死锁问题#优选材料_第3页
死锁问题#优选材料_第4页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 哲学家就餐问题与死锁2.1 设计目的理解死锁的概念,掌握死锁预防方法。死锁是进程并发执行过程中可能出现的现象,哲学家就餐问题是描述死锁的经典例子。假设有几位哲学家围坐在一张餐桌旁,桌上有吃不尽的食品,每两位哲学家之间摆放着一根筷子,筷子的个数与哲学家的数量相等,每一位哲学家要么思考,要么等待,要么拿起左右两根筷子进餐。本设计假设有五个哲学家和五根筷子,它们的编号都是从0到4。 如果每位哲学家都拿起左边的筷子,就会发生死锁。为了防止死锁,可以采用资源预分配法或者资源按序分配法。资源预分配法是指进程在运行前一次性地向系统申请它所需要的全部资源,如果系统当前不能够满足进程的全部资源请求,则不分配资

2、源, 此进程暂不投入运行,如果系统当前能够满足进程的全部资源请求, 则一次性地将所申请的资源全部分配给申请进程。资源按序分配法是指事先将所有资源类全排序, 即赋予每一个资源类一个唯一的整数,规定进程必需按照资源编号由小到大的次序申请资源。在哲学家就餐问题中,要采用资源预分配法只需让每个哲学家同时申请左右两根筷子。要采用资源按序分配法只需规定每个哲学家先申请左右两根筷子中编号小的筷子,再申请编号大的筷子。2.2 设计要求利用多线程技术编写哲学家就餐程序,使之在运行时能演示产生死锁的情况,也能演示采用死锁防止方法后不产生死锁的情况。程序要采用简单的控制台界面,运行后在屏幕上显示功能菜单,列出该程序

3、具有的功能,供用户选择,用户选择功能后应该转到相应的处理程序。程序应该包括以下功能:(1)演示死锁现象;(2)通过资源按序分配法防止死锁;(3)通过资源预分配法防止死锁;(4)退出。2.3 设计步骤2.3.1 程序结构设计程序需要六个线程,主线程用于显示主菜单,接收用户的功能选择;五个哲学家线程用于模拟哲学家的活动,即不停地思考、饥饿、进食。相邻的两个哲学家线程需要共享他们中间的同一根筷子,因此对每一根筷子的使用要互斥,用互斥体数组h_mutex_chopsticks来实现。主线程创建五个哲学家线程后要等待所有哲学家结束,用线程句柄数组h_thread来表示五个线程,主线程通过等待这五个线程句

4、柄来实现同步。该程序共有7个函数,这些函数可以分成4组。各组包含的函数及其功能如表2-1所示。组别包括函数函数功能一main()显示主菜单,接收用户的选择并执行相应的功能。二deadlock_philosopher()deadlock()演示死锁情况的哲学家线程函数初始化函数:创建五个哲学家并等待它们结束三ordered_allocation_philosopher()ordered_allocation()通过按序分配法防止死锁的哲学家线程函数初始化函数:创建五个哲学家并等待它们结束四pre_allocation_philosopher()pre_allocation()通过预先分配法防止死

5、锁的哲学家线程函数初始化函数:创建五个哲学家并等待它们结束图2-1 函数及其功能2.3.2 算法设计下面给出主要函数的算法描述。(1)deadlock_philosopher函数 while(1)随机等待一段时间;提示等待左边筷子;申请左边筷子;随机等待一段时间;提示等待右边筷子;申请右边筷子;提示正在进餐;放下左边筷子;放下右边筷子;(2)ordered_allocation_philosopher函数 while(1)随机等待一段时间;提示等待左右两边编号较小的筷子;申请编号较小的筷子;随机等待一段时间;提示等待左右两边编号较大的筷子;申请编号较大的筷子;提示正在进餐;放下编号较小的筷子;

6、放下编号较大的筷子;(3)pre_allocation_philosopher函数 while(1)提示等待左边筷子;提示等待右边筷子;同时申请左边和右边两根筷子;提示正在进餐;随机等待一段时间;放下左边筷子;放下右边筷子;(4)deadlock函数为每根筷子创建一个互斥信号量;创建五个可能产生死锁的哲学家线程;等待五个哲学家线程结束;其他的初始化函数与deadlock()的算法相同,只不过在创建线程时使用不同的线程函数。在windows中可以用系统调用WaitForMultipleObjects()同时申请两份资源,具体解法如下所示。#define N 5 typedef enumthink

7、ing, hungry, eatingstatus; status stateN; semaphore selfN;semaphore mutex = 1;void test(int i) if(statei = hungry)& (state(i-1)%N != eating)& (state(i+1)%N != eating) statei = eating; V(selfi); void pick_chopsticks(int i) P(mutex); statei = hungry; test(i); V(mutex); P(selfi); void put_chopsticks(in

8、t i) P(mutex); statei = thinking; test(i-1)%N); test(i+1)%N); V(mutex); void philosopher(int i) while(1) think(); pick_chopsticks(i); eat(); put_chopsticks(i); void main int i; for(i=0;i5;i+)statei = thingking;selfi.value = 0; 在上述程序中, 自定义数据类型status用来枚举哲学家的状态,数组state用来存放五个哲学家的状态,由于该数组是全局变量,所以用信号灯变量mu

9、tex实现对它的互斥访问。信号量数组self包含五个元素,每个元素的初始值皆为0,当第i号哲学家不具备进食条件时,会将自己阻塞在信号量selfi上。函数test用于测试i号哲学家是否具备进食的条件。i号哲学家可以进食必须同时满足以下条件:i号哲学家饥饿,左边哲学家不在进食,右边哲学家不在进食。2.3.3 参考源代码2.3.3.1 windows下的参考源程序#include #include #include #include #include #include #include #define MAX_PHILOSOPHERS 5 /待测试的哲学家数#define ZERO 48 /数字0的

10、ASCII码#define DELAY rand()%25HANDLE h_mutex_chopsticksMAX_PHILOSOPHERS; /互斥体数组,每根筷子需要一个互斥体int thread_numberMAX_PHILOSOPHERS=0,1,2,3,4;/会产生死锁的哲学家线程int deadlock_philosopher(LPVOID data)int philosopher_number=*(int *)(data); /哲学家编号for(;)srand( (unsigned)time( NULL ) * ( philosopher_number+ 1) ); Sleep(

11、DELAY); printf(%s%c%s%cn,Philosopher ,ZERO+philosopher_number, is waiting chopstick ,(ZERO+philosopher_number); WaitForSingleObject(h_mutex_chopsticksphilosopher_number, INFINITE); printf(%s%c%s%cn,Philosopher ,ZERO+philosopher_number, got chopstick ,(ZERO+philosopher_number);Sleep(DELAY/4);printf(%

12、s%c%s%cn,Philosopher ,ZERO+philosopher_number, is waiting chopstick ,(ZERO+(1+philosopher_number)%MAX_PHILOSOPHERS); WaitForSingleObject(h_mutex_chopsticks(1+philosopher_number)%MAX_PHILOSOPHERS), INFINITE); printf(%s%c%s%cn,Philosopher ,ZERO+philosopher_number, got chopstick ,(ZERO+(1+philosopher_n

13、umber)%MAX_PHILOSOPHERS); printf(%s%c%sn,Philosopher ,ZERO+philosopher_number, is eating.); Sleep(DELAY); ReleaseMutex(h_mutex_chopsticksphilosopher_number);printf(%s%c%s%cn,Philosopher ,ZERO+philosopher_number, released chopstick ,ZERO+philosopher_number); ReleaseMutex(h_mutex_chopsticks(1+philosop

14、her_number)%MAX_PHILOSOPHERS);printf(%s%c%s%cn,Philosopher ,ZERO+philosopher_number, released chopstick ,(ZERO+(1+philosopher_number)%MAX_PHILOSOPHERS); Sleep(DELAY); / end forreturn 0;/死锁时的初始化程序void deadlock()int i=0;HANDLE h_threadMAX_PHILOSOPHERS;printf(可能出现死锁的哲学家就餐问题n);for(i=0;iMAX_PHILOSOPHERS;

15、i+)h_mutex_chopsticksi=CreateMutex(NULL,FALSE,NULL);for(i=0;iMAX_PHILOSOPHERS;i+)h_threadi=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(deadlock_philosopher),&thread_numberi,0,NULL);WaitForMultipleObjects(MAX_PHILOSOPHERS,h_thread,TRUE,-1);/通过按序分配资源预防死锁的哲学家线程int ordered_allocation_philosopher(LPVOID

16、 data)int philosopher_number=*(int *)(data);for(;)srand( (unsigned)time( NULL ) * ( philosopher_number+ 1) ); Sleep(DELAY);if(philosopher_number=MAX_PHILOSOPHERS-1) printf(%s%c%s%cn,Philosopher ,ZERO+philosopher_number, is waiting chopstick ,(ZERO+(1+philosopher_number)%MAX_PHILOSOPHERS); WaitForSin

17、gleObject(h_mutex_chopsticks(1+philosopher_number)%MAX_PHILOSOPHERS, INFINITE); Sleep(DELAY/4); printf(%s%c%s%cn,Philosopher ,ZERO+philosopher_number, is waiting chopstick ,ZERO+philosopher_number); WaitForSingleObject(h_mutex_chopsticksphilosopher_number, INFINITE);else printf(%s%c%s%cn,Philosopher

18、 ,ZERO+philosopher_number, is waiting chopstick ,ZERO+philosopher_number); WaitForSingleObject(h_mutex_chopsticksphilosopher_number, INFINITE); Sleep(DELAY/4); printf(%s%c%s%cn,Philosopher ,ZERO+philosopher_number, is waiting chopstick ,ZERO+(1+philosopher_number)%MAX_PHILOSOPHERS); WaitForSingleObj

19、ect(h_mutex_chopsticks(1+philosopher_number)%MAX_PHILOSOPHERS, INFINITE); printf(%s%c%sn,Philosopher ,ZERO+philosopher_number, is eating.); Sleep(DELAY); printf(%s%c%s%cn,Philosopher ,ZERO+philosopher_number, is releasing chopstick ,ZERO+philosopher_number); ReleaseMutex(h_mutex_chopsticksphilosophe

20、r_number);printf(%s%c%s%cn,Philosopher ,ZERO+philosopher_number, is releasing chopstick ,ZERO+(1+philosopher_number)%MAX_PHILOSOPHERS); ReleaseMutex(h_mutex_chopsticks(1+philosopher_number)%MAX_PHILOSOPHERS); Sleep(DELAY); / end forreturn 0;/通过按序分配资源预防死锁的初始化程序void ordered_allocation()int i=0;HANDLE

21、h_threadMAX_PHILOSOPHERS;printf(可能出现死锁的哲学家就餐问题n);for(i=0;iMAX_PHILOSOPHERS;i+)h_mutex_chopsticksi=CreateMutex(NULL,FALSE,NULL);for(i=0;iMAX_PHILOSOPHERS;i+)h_threadi=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(ordered_allocation_philosopher),&thread_numberi,0,NULL);WaitForMultipleObjects(MAX_PHILOS

22、OPHERS,h_thread,TRUE,-1);/通过资源预分配法预防死锁的哲学家线程int pre_alloction_philosopher(LPVOID data)int philosopher_number=*(int *)(data);HANDLE h_mutex_leftandright_chopsticks2;h_mutex_leftandright_chopsticks0=h_mutex_chopsticksphilosopher_number; h_mutex_leftandright_chopsticks1=h_mutex_chopsticks(1+philosopher

23、_number)%MAX_PHILOSOPHERS;for(;)srand( (unsigned)time( NULL ) * ( philosopher_number+ 1) ); Sleep(DELAY); printf(%s%c%s%cn,Philosopher ,ZERO+philosopher_number, is waiting chopstick ,ZERO+philosopher_number); printf(%s%c%s%cn,Philosopher ,ZERO+philosopher_number, is waiting chopstick ,ZERO+(1+philos

24、opher_number)%MAX_PHILOSOPHERS); WaitForMultipleObjects(2, h_mutex_leftandright_chopsticks, TRUE, INFINITE); printf(%s%c%sn,Philosopher ,ZERO+philosopher_number, is eating.); Sleep(DELAY); printf(%s%c%s%cn,Philosopher ,ZERO+philosopher_number, is releasing chopstick ,ZERO+philosopher_number); Releas

25、eMutex(h_mutex_chopsticksphilosopher_number);printf(%s%c%s%cn,Philosopher ,ZERO+philosopher_number, is releasing chopstick ,ZERO+(1+philosopher_number)%MAX_PHILOSOPHERS); ReleaseMutex(h_mutex_chopsticks(1+philosopher_number)%MAX_PHILOSOPHERS); Sleep(DELAY); / end forreturn 0;/通过资源预分配法预防死锁的初始化程序void pre_alloction()int i=0;HANDLE h_threadMAX_PHILOSOPHERS;printf(可能出现死锁的哲学家就餐问题n);for(i=0;iMAX_PHILOSOPHERS;i+)h_mutex_chopsticksi=CreateMutex(NULL,FALSE,NULL);for(i=0;iMAX_PHILOSOPHERS;i+)h_threadi=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(pre_alloction_philosopher),&thread_numberi,0,N

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论