问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

哲学家进餐问题的C语言实现

创作时间:
作者:
@小白创作中心

哲学家进餐问题的C语言实现

引用
CSDN
1.
https://blog.csdn.net/c3091158291/article/details/144381905

“哲学家进餐问题”是一个经典的同步与并发编程问题,由艾尔弗雷德·阿尔维和丹尼斯·里奇在20世纪70年代提出,旨在探讨资源共享和互斥的问题。该问题主要涉及五位哲学家围坐在一张圆桌上,他们在思考和进餐之间交替进行。每位哲学家面前有一根筷子(或叉子),而吃饭需要同时握住左右两根筷子。这个问题强调了以下几点:

  1. 资源竞争:每位哲学家都需要访问共享资源(筷子),可能会导致资源竞争和死锁。
  2. 同步与互斥:确保在任何时刻只有一位哲学家能使用筷子,同时避免死锁,即所有哲学家都在等待彼此释放筷子,无法继续。
  3. 解决死锁方案:该问题有多种解决方案,如引入一个外部的“管家”来控制筷子的使用,或通过改变哲学家的取餐顺序来减少死锁的可能性。

本文通过控制哲学家同时进餐的人数不超过人数减一(4)来确定:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <windows.h> // 包含 Sleep 函数
#include <time.h>

#define NUM_PHILOSOPHERS 5
#define NUM_CHOPSTICK 5

sem_t chopstick[NUM_CHOPSTICK];  // 筷子信号量
sem_t count; // 设置一个count

void* philosopher(void* num) {
    int philosopher_number = *(int*)num;  // 将 void* 转换为 int*,因为在create_pthread时传入参数类型只能是void*
    sem_wait(&count);  //请求进入房间进餐 当count为0时 不能允许哲学家再进来了
    printf("第%d个哲学家正在尝试拿左边的筷子...\n", philosopher_number);
    sem_wait(&chopstick[philosopher_number - 1]);
    printf("第%d个哲学家成功拿到左边的筷子...\n", philosopher_number);
    printf("第%d个哲学家正在尝试拿右边的筷子...\n", philosopher_number);
    sem_wait(&chopstick[philosopher_number % 5]);  // 先拿左边再拿右边
    printf("第%d个哲学家成功拿到右边的筷子...\n", philosopher_number);
    printf("第%d个哲学家正在进餐...\n", philosopher_number);
    Sleep(2000);
    sem_post(&chopstick[philosopher_number - 1]);
    sem_post(&chopstick[philosopher_number % 5]);  // 先放左边再放右边
    sem_post(&count);  //离开饭桌释放信号量
    printf("第%d个哲学家继续思考...\n", philosopher_number);
    return NULL; // 添加返回值
}

int main() {
    srand(time(NULL));  // 设置随机数种子
    sem_init(&count, 0, 4);  // 最多有四个哲学家可以进来
    pthread_t philosophers[NUM_PHILOSOPHERS];
    // 使用循环初始化信号量
    for (int i = 0; i < NUM_CHOPSTICK; i++) {
        sem_init(&chopstick[i], 0, 1);  // 每个筷子初始化为 1(可用)
    }
    int temp = 1;
    // 创建哲学家线程
    for (int i = 1; i <= NUM_PHILOSOPHERS; i++) {
        int* id = malloc(sizeof(int));  // 动态分配内存
        *id = i;
        pthread_create(&philosophers[i - 1], NULL, philosopher, id);
    }
    // 等待哲学家线程结束
    for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
        pthread_join(philosophers[i], NULL);
    }
    // 销毁信号量
    for (int i = 0; i < NUM_CHOPSTICK; i++) {
        sem_destroy(&chopstick[i]);
    }
    return 0;
}
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号