以下是一个简单的Linux下哲学家就餐问题的C语言实现,其中使用了pthread库和信号量。

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

#define N 5 // 哲学家数量
#define LEFT (i + N - 1) % N // 左邻居编号
#define RIGHT (i + 1) % N // 右邻居编号
#define THINKING 0 // 哲学家在思考
#define HUNGRY 1 // 哲学家饥饿
#define EATING 2 // 哲学家在就餐

int state[N]; // 存储每个哲学家的状态
pthread_mutex_t mutex; // 互斥锁
sem_t sem[N]; // 信号量

void philosopher(int i)
{
    while (1) {
        printf('哲学家 %d 正在思考...
', i);
        sleep(2);
        pickup(i); // 尝试拿起叉子
        printf('哲学家 %d 开始就餐...
', i);
        sleep(2);
        putdown(i); // 放下叉子
    }
}

void pickup(int i)
{
    pthread_mutex_lock(&mutex);
    state[i] = HUNGRY; // 改变自己的状态为饥饿
    test(i); // 尝试拿起叉子
    pthread_mutex_unlock(&mutex);
    sem_wait(&sem[i]); // 如果没有成功拿起叉子,则等待信号量
}

void putdown(int i)
{
    pthread_mutex_lock(&mutex);
    state[i] = THINKING; // 改变自己的状态为思考
    test(LEFT); // 尝试让左邻居拿起叉子
    test(RIGHT); // 尝试让右邻居拿起叉子
    pthread_mutex_unlock(&mutex);
}

void test(int i)
{
    if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING) {
        state[i] = EATING; // 改变自己的状态为就餐
        sem_post(&sem[i]); // 发送信号量,允许自己拿起叉子
    }
}

int main()
{
    int i;
    pthread_t tid[N];
    pthread_mutex_init(&mutex, NULL);
    for (i = 0; i < N; i++) {
        sem_init(&sem[i], 0, 0); // 初始化信号量
        state[i] = THINKING; // 所有哲学家一开始都在思考
        pthread_create(&tid[i], NULL, (void *) philosopher, (void *) i); // 创建哲学家线程
        printf('哲学家 %d 坐在桌子旁边...
', i);
    }
    for (i = 0; i < N; i++) {
        pthread_join(tid[i], NULL); // 等待哲学家线程结束
    }
    return 0;
}

在这个实现中,每个哲学家被表示为一个线程,每个线程中都调用了philosopher函数,该函数表示哲学家的行为。他们会不断地思考、尝试拿起叉子、就餐和放下叉子。

pickup函数中,当一个哲学家尝试拿起叉子时,它将改变自己的状态为饥饿,然后尝试拿起叉子。如果拿不起来,它将等待信号量。在putdown函数中,当一个哲学家放下叉子时,它将改变自己的状态为思考,然后尝试让左右邻居拿起叉子。在test函数中,当一个哲学家尝试拿起叉子时,它将检查左右邻居是否正在就餐,如果没有就餐的邻居,它将改变自己的状态为就餐,并发送信号量。

main函数中,我们创建了每个哲学家的线程,并等待线程结束。我们还初始化了互斥锁和信号量,以确保哲学家之间的同步。

Linux下哲学家就餐问题C语言实现 - 使用pthread和信号量

原文地址: https://www.cveoy.top/t/topic/nA69 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录