不预防死锁情况下的哲学家就餐问题
这个问题其实还是挺有意思的
死锁是进程并发执行过程中可能出现的现象,哲学家就餐问题是描述死锁的经典例子。假设有几位哲学家围坐在一张餐桌旁,桌上有吃不尽的食品,每两位哲学家之间摆放着一根筷子,筷子的个数与哲学家的数量相等,每一位哲学家要么思考,要么等待,要么拿起左右两根筷子进餐。本设计假设有五个哲学家和五根筷子,它们的编号都是从0到4。 如果每位哲学家都拿起左边的筷子,就会发生死锁。
程序需要六个线程,主线程用于显示功能描述;五个哲学家线程用于模拟哲学家的活动,即不停地思考、饥饿、进食。相邻的两个哲学家线程需要共享他们中间的同一根筷子,因此对每一根筷子的使用要互斥,用互斥体数组h_mutex_chopsticks来实现。主线程创建五个哲学家线程后要等待所有哲学家结束,用线程句柄数组h_thread来表示五个线程,主线程通过等待这五个线程句柄来实现同步。
直接放代码了,就是申请
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <semaphore.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
pthread_mutex_t chopsticks[5];// 互斥信号量
int just_number[5] = {0, 1, 2, 3, 4};//数字
void *deadlock_philosopher(void *data) {
int philosopher_number = *(int *)(data);
//int i = 0;
for (;;) {
srand((unsigned)time(NULL) * (philosopher_number + 1));//随机申请一个数
sleep(0.1);//思考
/*if (i >= 5) {//就5个,多了回到0
i = 0;
}
else{
i++;
}*/
//对一个筷子加锁
printf("%d号哲学家在等待%d号筷子\n",philosopher_number,philosopher_number);
pthread_mutex_lock(&chopsticks[philosopher_number]);
//sleep(0.1/4);
//对旁边的筷子加个锁
printf("%d号哲学家在等待%d号筷子\n",philosopher_number,(1 + philosopher_number) % 5);
pthread_mutex_lock(&chopsticks[(1 + philosopher_number) % 5]);
printf("%d号哲学家正在吃饭\n\n", philosopher_number);
sleep(0.1);
printf("%d号哲学家在等待%d号筷子\n",philosopher_number,philosopher_number);//放下筷子进行解锁
pthread_mutex_unlock(&chopsticks[philosopher_number]);
printf("%d号哲学家在等待%d号筷子\n",philosopher_number,(1 + philosopher_number) % 5);//对另一根筷子解锁
pthread_mutex_unlock(&chopsticks[(1 + philosopher_number) % 5]);
}
return 0;
}
void deadlock() {
int i = 0;
pthread_t h_thread[5];//声明线程ID,哲学家的编号
printf("\n");
for (i = 0; i < 5; i++) {
pthread_mutex_init(&chopsticks[i], NULL);// 5 互斥锁 初始化
};
for (i = 0; i < 5; i++) {
pthread_create(&h_thread[i], NULL, deadlock_philosopher, &just_number[i]);//创造线程
};
for (i = 0; i < 5; i++) {
pthread_join(h_thread[i], NULL);//等待线程结束, 线程 资源回收函数
}
}
int main(int argc, char *argv[]) {
while (1) {
deadlock();
}
return 0;
}
大概就是这个样子了

浙公网安备 33010602011771号