哲学家进餐问题3种代码 c
时间: 2023-09-04 11:02:43 浏览: 96
哲学家进餐问题涉及到一个经典的多线程同步问题,即多个哲学家围坐在一张圆桌旁,每个哲学家面前放着一碗饭和一只叉子。哲学家思考和进餐,思考时需要两只叉子,进餐时需要拿起两只叉子。问题的关键在于如何保证每个哲学家都能得到他所需要的两只叉子而不产生死锁。
以下是三种解决哲学家进餐问题的代码示例:
代码1:
1. 创建一个共享的锁数组,每个元素代表一只叉子;
2. 每个哲学家线程首先尝试获取自己左边的叉子,然后再尝试获取自己右边的叉子;
3. 若成功获取到两只叉子,则可以进餐,进餐完成后释放两只叉子;
4. 若未能同时获取到两只叉子,则释放已经获取到的叉子,进入等待状态,等待其他线程释放叉子。
代码2:
1. 创建一个共享的信号量数组,每个元素代表一只叉子;
2. 每个哲学家线程首先尝试获取自己左边的叉子,然后再尝试获取自己右边的叉子;
3. 若成功获取到两只叉子,则可以进餐,进餐完成后释放两只叉子;
4. 若未能同时获取到两只叉子,则释放已经获取到的叉子,进入等待状态,等待其他线程释放叉子。
代码3:
1. 创建一个共享的计数器,代表可用的叉子数量;
2. 每个哲学家线程首先尝试获取自己左边的叉子,然后再尝试获取自己右边的叉子;
3. 若成功获取到两只叉子,则可以进餐,进餐完成后释放两只叉子,并将计数器加1;
4. 若未能同时获取到两只叉子,则释放已经获取到的叉子,进入等待状态,等待其他线程释放叉子并将计数器加1。
这三种代码的目标都是确保每个哲学家都能获取到所需要的两只叉子,避免死锁情况的发生。具体使用哪种代码取决于实际需求和环境。
相关问题
哲学家进餐问题c代码
哲学家进餐问题是一个经典的并发问题,其描述了五个哲学家围坐在一张圆桌前,每个哲学家面前有一碗饭和一只筷子。哲学家只有在同时拿到左右两只筷子时才能进餐,进餐完毕后放下筷子继续思考人生。如果所有哲学家都拿起了左手边的筷子,那么他们就会陷入死锁状态,无法继续进餐。
下面是哲学家进餐问题的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;
}
```
进程哲学家进餐问题c代码
以下是进程实现哲学家进餐问题的C代码,其中使用了信号量来解决死锁问题,并且在控制台输出每个哲学家的工作状态:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.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]; // 哲学家状态数组
sem_t mutex; // 互斥信号量
sem_t s[N]; // 哲学家信号量
void test(int i) {
if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING) {
state[i] = EATING;
printf("哲学家 %d 正在就餐\n", i);
sem_post(&s[i]);
}
}
void take_forks(int i) {
sem_wait(&mutex);
state[i] = HUNGRY;
printf("哲学家 %d 饿了\n", i);
test(i);
sem_post(&mutex);
sem_wait(&s[i]);
sleep(1);
}
void put_forks(int i) {
sem_wait(&mutex);
state[i] = THINKING;
printf("哲学家 %d 放下了叉子\n", i);
test(LEFT);
test(RIGHT);
sem_post(&mutex);
}
void *philosopher(void *arg) {
int i = *(int *)arg;
while (1) {
printf("哲学家 %d 正在思考\n", i);
sleep(1);
take_forks(i);
put_forks(i);
}
}
int main() {
pthread_t tid[N];
int i, num[N];
sem_init(&mutex, 0, 1);
for (i = 0; i < N; i++) {
sem_init(&s[i], 0, 0);
num[i] = i;
state[i] = THINKING;
}
for (i = 0; i < N; i++) {
pthread_create(&tid[i], NULL, philosopher, &num[i]);
}
for (i = 0; i < N; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}
```
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)