C语言实现哲学家进餐问题,要求如下:(1)只有拿到两只筷子时,哲学家才能吃饭。 (2)如果筷子已被别人拿走,则必须等别人吃完之后才能拿到筷子。 (3)任一哲学家在自己未拿到两只筷子吃饭前,不会放下手中拿到的筷子。 课程设计要求:
时间: 2024-03-12 20:45:37 浏览: 21
下面是C语言实现哲学家进餐问题的代码,满足题目要求:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define N 5 // 哲学家数量
sem_t forks[N]; // 叉子信号量
sem_t mutex; // 互斥信号量
void *philosopher(void *arg) {
int id = *(int *)arg;
int left_fork = id;
int right_fork = (id + 1) % N;
while (1) {
// 思考
printf("Philosopher %d is thinking.\n", id);
sleep(rand() % 3);
// 拿起左边的叉子
sem_wait(&forks[left_fork]);
printf("Philosopher %d picks up fork %d.\n", id, left_fork);
// 拿起右边的叉子
sem_wait(&forks[right_fork]);
printf("Philosopher %d picks up fork %d.\n", id, right_fork);
// 进餐
printf("Philosopher %d is eating.\n", id);
sleep(rand() % 3);
// 放下右边的叉子
sem_post(&forks[right_fork]);
printf("Philosopher %d puts down fork %d.\n", id, right_fork);
// 放下左边的叉子
sem_post(&forks[left_fork]);
printf("Philosopher %d puts down fork %d.\n", id, left_fork);
}
}
int main() {
pthread_t tid[N];
int id[N];
// 初始化叉子信号量
for (int i = 0; i < N; i++) {
sem_init(&forks[i], 0, 1);
}
// 初始化互斥信号量
sem_init(&mutex, 0, 1);
// 创建哲学家线程
for (int i = 0; i < N; i++) {
id[i] = i;
pthread_create(&tid[i], NULL, philosopher, &id[i]);
}
// 等待哲学家线程结束
for (int i = 0; i < N; i++) {
pthread_join(tid[i], NULL);
}
// 销毁信号量
for (int i = 0; i < N; i++) {
sem_destroy(&forks[i]);
}
sem_destroy(&mutex);
return 0;
}
```
在代码中,创建了叉子信号量数组 `forks` 和一个互斥信号量 `mutex`。每个哲学家的编号从0到4,通过 `left_fork` 和 `right_fork` 计算出自己左右两只叉子的编号。
在哲学家线程的循环中,先思考一段随机时间,然后拿起左边的叉子,如果左边的叉子已经被其他哲学家拿走,那么当前哲学家就会一直等待,直到左边的叉子被释放。同样地,如果右边的叉子已经被其他哲学家拿走,那么当前哲学家也会一直等待,直到右边的叉子被释放。
获取到左右两只叉子后,哲学家就可以开始进餐了,调用 `sleep` 函数模拟吃饭的过程。吃完饭后,哲学家要将右边的叉子和左边的叉子都放下,即调用 `sem_post` 函数释放叉子。
最后,在 `main` 函数中创建哲学家线程,并等待哲学家线程结束后销毁信号量。