写一段C语言代码来实现哲学家就餐问题
时间: 2023-10-26 11:11:16 浏览: 334
哲学家就餐问题是一个经典的并发编程问题,涉及到多个哲学家(线程)在一张圆形桌子上就餐,每个哲学家需要左右两边的筷子(资源)才能吃饭,但每次只能有一个哲学家持有一只筷子,否则会发生死锁。
以下是一个简单的解决方案,使用互斥锁和条件变量来实现:
```
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define NUM_PHILOSOPHERS 5
pthread_mutex_t chopsticks[NUM_PHILOSOPHERS];
pthread_cond_t forks_available[NUM_PHILOSOPHERS];
void *philosopher(void *arg) {
int id = *(int *)arg;
int left = id;
int right = (id + 1) % NUM_PHILOSOPHERS;
while (1) {
// 每次循环开始时都尝试获取左右两个筷子
pthread_mutex_lock(&chopsticks[left]);
pthread_mutex_lock(&chopsticks[right]);
printf("Philosopher %d is eating\n", id);
usleep(1000000); // 模拟吃饭时间
// 吃完饭后释放左右两个筷子
pthread_mutex_unlock(&chopsticks[left]);
pthread_mutex_unlock(&chopsticks[right]);
printf("Philosopher %d is thinking\n", id);
usleep(1000000); // 模拟思考时间
}
return NULL;
}
int main() {
pthread_t philosophers[NUM_PHILOSOPHERS];
int ids[NUM_PHILOSOPHERS];
// 初始化互斥锁和条件变量
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_mutex_init(&chopsticks[i], NULL);
pthread_cond_init(&forks_available[i], NULL);
}
// 创建哲学家线程
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
ids[i] = i;
pthread_create(&philosophers[i], NULL, philosopher, &ids[i]);
}
// 等待哲学家线程结束
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_join(philosophers[i], NULL);
}
// 销毁互斥锁和条件变量
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_mutex_destroy(&chopsticks[i]);
pthread_cond_destroy(&forks_available[i]);
}
return 0;
}
```
在这个程序中,每个哲学家线程不断循环,尝试获取左右两个筷子并吃饭,吃完饭后释放筷子并思考。互斥锁用于保证同一时间只有一个哲学家持有同一个筷子,避免死锁的发生。条件变量用于在筷子被释放时通知其他哲学家可以获取这个筷子了。
阅读全文