不预防死锁情况下的哲学家就餐问题

这个问题其实还是挺有意思的

死锁是进程并发执行过程中可能出现的现象,哲学家就餐问题是描述死锁的经典例子。假设有几位哲学家围坐在一张餐桌旁,桌上有吃不尽的食品,每两位哲学家之间摆放着一根筷子,筷子的个数与哲学家的数量相等,每一位哲学家要么思考,要么等待,要么拿起左右两根筷子进餐。本设计假设有五个哲学家和五根筷子,它们的编号都是从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;
}

 

 

大概就是这个样子了

 

posted @   繁星藏碎月  阅读(370)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示