信号量解决哲学家进餐问题

参考线程同步之信号量(sem_init,sem_post,sem_wait) - 郑志强Aloha - 博客园

以及《操作系统概念》第七版 第六章 项目:生产者-消费者问题

题目描述:

哲学家进餐问题描述有五个哲学家,他们的生活方式是交替地进行思考和进餐,n哲学家们共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,n平时哲学家进行思考,饥饿时便试图取其左、右最靠近他的筷子,只有在他拿到两支筷子时才能进餐,n进餐完毕,放下筷子又继续思考。

如图。

 


 

编号都为0-4。哲学家0-3左边的筷子编号为i,右边为i+1。

哲学家4左边的筷子为4,右边为0。(因为是圆桌嘛)

代码:

这里ret应该用int。。忘了改了。


 

 


 

 


 

 


 

 


 

 


 

效果图:

 


 

遇到的问题:

 


 

解决:应该放到main函数里初始化

 


 

解决:太低级的错误了。。。。居然用了函数名做变量名。

 


 

转载于:https://www.cnblogs.com/lqerio/p/11117672.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用信号解决哲学家进餐问题的 C 语言实现: ``` #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #define N 5 // 哲学家 #define LEFT (i + N - 1) % N // 左边的哲学家 #define RIGHT (i + 1) % N // 右边的哲学家 sem_t chopstick[N]; // 餐叉信号 sem_t mutex; // 互斥信号 void *philosopher(void *arg) { int i = *((int *) arg); while (1) { // 思考 printf("Philosopher %d is thinking\n", i); sleep(rand() % 5); // 获取两个相邻的餐叉 printf("Philosopher %d is hungry\n", i); sem_wait(&mutex); sem_wait(&chopstick[LEFT]); sem_wait(&chopstick[RIGHT]); sem_post(&mutex); // 就餐 printf("Philosopher %d is eating\n", i); sleep(rand() % 5); // 释放两个餐叉 sem_post(&chopstick[LEFT]); sem_post(&chopstick[RIGHT]); } } int main() { pthread_t tid[N]; int i; // 初始化信号 sem_init(&mutex, 0, 1); for (i = 0; i < N; i++) { sem_init(&chopstick[i], 0, 1); } // 创建哲学家线程 for (i = 0; i < N; i++) { pthread_create(&tid[i], NULL, philosopher, &i); } // 等待哲学家线程结束 for (i = 0; i < N; i++) { pthread_join(tid[i], NULL); } // 销毁信号 sem_destroy(&mutex); for (i = 0; i < N; i++) { sem_destroy(&chopstick[i]); } return 0; } ``` 在上面的代码中,我们创建了 N 个哲学家线程,每个哲学家线程都循环执行思考、就餐和释放餐叉的操作。在获取餐叉时,我们使用了互斥信号 mutex 来保证同一时间只有一个哲学家能够获取餐叉,避免死锁和饥饿等问题。同时,每个哲学家都有两个相邻的餐叉,分别为左边的餐叉和右边的餐叉,我们使用了 chopstick 数组来表示这些餐叉的信号。在获取餐叉时,先获取互斥信号 mutex,然后再获取左边和右边的餐叉信号,这样就能保证每个哲学家都能安全地获取到两个相邻的餐叉,避免死锁和饥饿等问题。在就餐完成后,释放餐叉时,也需要先释放互斥信号 mutex,然后再释放左边和右边的餐叉信号。最后,我们在主函数中创建哲学家线程,等待哲学家线程结束,然后销毁信号
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值