哲学家进餐问题c代码
时间: 2023-12-31 22:04:55 浏览: 109
哲学家进餐问题的代码
哲学家进餐问题是一个经典的并发问题,其描述了五个哲学家围坐在一张圆桌前,每个哲学家面前有一碗饭和一只筷子。哲学家只有在同时拿到左右两只筷子时才能进餐,进餐完毕后放下筷子继续思考人生。如果所有哲学家都拿起了左手边的筷子,那么他们就会陷入死锁状态,无法继续进餐。
下面是哲学家进餐问题的C语言代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.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; // 互斥锁
pthread_cond_t cond[N]; // 条件变量
void test(int i) {
if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING) {
state[i] = EATING;
printf("哲学家 %d 拿到了左右两只筷子,开始进餐\n", i);
pthread_cond_signal(&cond[i]); // 唤醒等待该哲学家的线程
}
}
void take_forks(int i) {
pthread_mutex_lock(&mutex); // 加锁
state[i] = HUNGRY;
printf("哲学家 %d 感到饥饿,开始思考人生\n", i);
test(i); // 尝试拿起左右两只筷子
while (state[i] != EATING) { // 如果没有拿到左右两只筷子,则等待
pthread_cond_wait(&cond[i], &mutex);
}
pthread_mutex_unlock(&mutex); // 解锁
}
void put_forks(int i) {
pthread_mutex_lock(&mutex); // 加锁
state[i] = THINKING;
printf("哲学家 %d 进餐完毕,放下了左右两只筷子,开始思考人生\n", i);
test(LEFT); // 尝试唤醒左右邻居
test(RIGHT);
pthread_mutex_unlock(&mutex); // 解锁
}
void *philosopher(void *arg) {
int i = *(int *)arg;
while (1) {
sleep(rand() % 5 + 1); // 思考一段时间
take_forks(i); // 拿起左右两只筷子
sleep(rand() % 5 + 1); // 进餐一段时间
put_forks(i); // 放下左右两只筷子
}
}
int main() {
pthread_t tid[N];
int i, id[N];
pthread_mutex_init(&mutex, NULL); // 初始化互斥锁
for (i = 0; i < N; i++) {
pthread_cond_init(&cond[i], NULL); // 初始化条件变量
id[i] = i;
pthread_create(&tid[i], NULL, philosopher, &id[i]); // 创建哲学家线程
}
for (i = 0; i < N; i++) {
pthread_join(tid[i], NULL); // 等待哲学家线程结束
}
return 0;
}
```
阅读全文