不预防死锁情况下的哲学家就餐问题
这个问题其实还是挺有意思的
死锁是进程并发执行过程中可能出现的现象,哲学家就餐问题是描述死锁的经典例子。假设有几位哲学家围坐在一张餐桌旁,桌上有吃不尽的食品,每两位哲学家之间摆放着一根筷子,筷子的个数与哲学家的数量相等,每一位哲学家要么思考,要么等待,要么拿起左右两根筷子进餐。本设计假设有五个哲学家和五根筷子,它们的编号都是从0到4。 如果每位哲学家都拿起左边的筷子,就会发生死锁。
程序需要六个线程,主线程用于显示功能描述;五个哲学家线程用于模拟哲学家的活动,即不停地思考、饥饿、进食。相邻的两个哲学家线程需要共享他们中间的同一根筷子,因此对每一根筷子的使用要互斥,用互斥体数组h_mutex_chopsticks来实现。主线程创建五个哲学家线程后要等待所有哲学家结束,用线程句柄数组h_thread来表示五个线程,主线程通过等待这五个线程句柄来实现同步。
直接放代码了,就是申请
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | #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; } |
大概就是这个样子了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)