1 设计目的
理解死锁的概念,掌握死锁预防方法。
死锁是进程并发执行过程中可能出现的现象,哲学家就餐问题是描述死锁的经典例子。
为了防止死锁,可以采用资源有序分配法。资源有序分配法是指事先将所有资源类全排序, 即赋予每一个资源类一个唯一的整数,规定进程必需按照资源编号由小到大的次序申请资源。
在哲学家就餐问题中,要采用资源有序分配法只需规定每个哲学家先申请左右两根筷子中编号小的筷子,再申请编号大的筷子。
2 设计要求
利用多线程技术编写哲学家就餐程序,演示采用死锁防止方法后不产生死锁的情况。
3 设计步骤
3.1 程序结构设计
程序需要六个线程,主线程用于显示功能描述;五个哲学家线程用于模拟哲学家的活动,即不停地思考、饥饿、进食。相邻的两个哲学家线程需要共享他们中间的同一根筷子,因此对每一根筷子的使用要互斥,用互斥体数组h_mutex_chopsticks来实现。主线程创建五个哲学家线程后要等待所有哲学家结束,用线程句柄数组h_thread来表示五个线程,主线程通过等待这五个线程句柄来实现同步。
3.2 算法设计
下面给出有序分配法函数ordered_allocation_philosopher和初始化函数ordered_allocation的算法描述。
ordered_allocation_philosopher函数
{
while(1){
随机等待一段时间;
提示等待左右两边编号较小的筷子;
申请编号较小的筷子;
随机等待一段时间;
提示等待左右两边编号较大的筷子;
申请编号较大的筷子;
提示正在进餐;
放下编号较小的筷子;
放下编号较大的筷子;
}
}
ordered_allocation函数
{
为每根筷子创建一个互斥信号量;
创建五个可能产生死锁的哲学家线程;
等待五个哲学家线程结束;
}
Windows系统下的程序代码
#include <stdio.h>
#include <conio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <time.h>
#define MAX_PHILOSOPHERS 5
#define DELAY (rand()%25)/1000
pthread_mutex_t h_mutex_chopsticks[MAX_PHILOSOPHERS]; //互斥体数组实现对每一根筷子的互斥使用
void* ordered_allocation_philosopher(void* data);
void* ordered_allocation();
//通过有序分配法防止死锁的哲学家线程函数
void* ordered_allocation_philosopher(void* data){
int philosopher_number=*(int