用P、V操作写出一个不会出现死锁的哲学家进餐问题
答案:1 悬赏:50 手机版
解决时间 2021-11-14 23:52
- 提问者网友:藍了天白赴美
- 2021-11-14 14:49
用P、V操作写出一个不会出现死锁的哲学家进餐问题
最佳答案
- 五星知识达人网友:上分大魔王
- 2021-11-14 15:29
哲学家就餐问题是一种典型的同步问题,它是由Dijkstra 提出并解决的。该问题描述
:有五个哲学家,他们的生活方式是交替的进行思考和进餐。哲学家们共用一张圆桌,
查看图片
设五个哲学家分别编号为A,B,C,D,E,桌子上放着五把筷子,筷子分别编号为 0,1,
2,3,4,桌子中央有一盘饭菜。五个哲学家都很有礼貌,都要等同时拿到身旁的两只筷子
才进餐,不然就只是等着继续思考,而且吃了一口之后又马上放下拿起的两根筷子,继续思
考。
用P V原语的方式实现
每个哲学家可用一个线程来模拟,信号量及其P、V操作的实现
定义一个semaphore 类 封装 P V原语模拟函数
(不妨设有6个哲学家,6只筷子, 每只筷子各对应一个信号量且每个信号量初始值应为1)
#include
#include
#include
#include "semaphore.h"
Semaphore::Semaphore(unsigned int semValue){
if(semValue > LONG_MAX)
semValue = LONG_MAX;
sem = CreateSemaphore(NULL,semValue,LONG_MAX,NULL);
Semaphore::~Semaphore(){
CloseHandle(sem);
void Semaphore::P(){
DWORD dw = WaitForSingleObject(sem, INFINITE);
assert(dw == WAIT_OBJECT_0);
void Semaphore::V(){
ReleaseSemaphore(sem,1,NULL);
假设偶数号哲学家先拿左边的筷子,右边的哲学家先拿起右边的筷子。
#include
#include "semaphore.h"
#include "thread.h"
#include
#include
#define N 6 //哲学家的个数
#define LEFt(i) (i+N-1)%N //左边的筷子
#define RIGHt(i) (i==N-1)?0:(i+N)%N //右边的筷子 编号为N的哲学家的右边的筷子编号为0
Semaphore ChopStick[N]={Semaphore(1),Semaphore(1),Semaphore(1),Semaphore(1),Semaphore(1),Semaphore(1)} ;
void Eating(int Ph_Id)
printf("Philosopher%d: \tI'm eating......\t",(int)Ph_Id);
void Sleeping(int Ph_Id)
printf("Philosopher%d:\tI'm sleeping......\t",(int)Ph_Id);
Sleep(rand()%10000);
void Thinking(int Ph_Id)
printf("Philosopher%d: \tI'm thinking......\t",(int)Ph_Id);
if (pid%2 == 0) //偶数号哲学家
Thinking(pid); //等待中
ChopStick[LEFt(pid)].P(); //先拿起左边的筷子,再拿起右边的筷子
ChopStick[RIGHt(pid)].P();
Eating(pid); //获得的两个信号量则eating
ChopStick[LEFt(pid)].V(); //先后释放左右信号量
ChopStick[RIGHt(pid)].V();
printf("\n");
else if(pid%2==1 ) //奇数号哲学家
Thinking(pid);
ChopStick[RIGHt(pid)].P(); //先拿起右边的筷子,再拿起左边的筷子
ChopStick[LEFt(pid)].P();
Eating(pid); //左右都得到筷子后则eating
ChopStick[RIGHt(pid)].V(); //先后释放右左信号量
ChopStick[LEFt(pid)].V();
printf("\n");
Sleeping(pid); //吃完睡上一会儿
int main(){
HANDLE hPhilosopher[N]; //为每个哲学家分配一个线程
int count =0 ;
for (int Philosopher_id =0 ;Philosopher_id hPhilosopher[Philosopher_id] = startThread(Philosopher,Philosopher_id);
if(count>5)
break;
::WaitForMultipleObjects(N,hPhilosopher,TRUE,INFINITE);
for (Philosopher_id = 0 ; Philosopher_id CloseHandle(hPhilosopher[Philosopher_id]);
:有五个哲学家,他们的生活方式是交替的进行思考和进餐。哲学家们共用一张圆桌,
查看图片
设五个哲学家分别编号为A,B,C,D,E,桌子上放着五把筷子,筷子分别编号为 0,1,
2,3,4,桌子中央有一盘饭菜。五个哲学家都很有礼貌,都要等同时拿到身旁的两只筷子
才进餐,不然就只是等着继续思考,而且吃了一口之后又马上放下拿起的两根筷子,继续思
考。
用P V原语的方式实现
每个哲学家可用一个线程来模拟,信号量及其P、V操作的实现
定义一个semaphore 类 封装 P V原语模拟函数
(不妨设有6个哲学家,6只筷子, 每只筷子各对应一个信号量且每个信号量初始值应为1)
#include
#include
#include
#include "semaphore.h"
Semaphore::Semaphore(unsigned int semValue){
if(semValue > LONG_MAX)
semValue = LONG_MAX;
sem = CreateSemaphore(NULL,semValue,LONG_MAX,NULL);
Semaphore::~Semaphore(){
CloseHandle(sem);
void Semaphore::P(){
DWORD dw = WaitForSingleObject(sem, INFINITE);
assert(dw == WAIT_OBJECT_0);
void Semaphore::V(){
ReleaseSemaphore(sem,1,NULL);
假设偶数号哲学家先拿左边的筷子,右边的哲学家先拿起右边的筷子。
#include
#include "semaphore.h"
#include "thread.h"
#include
#include
#define N 6 //哲学家的个数
#define LEFt(i) (i+N-1)%N //左边的筷子
#define RIGHt(i) (i==N-1)?0:(i+N)%N //右边的筷子 编号为N的哲学家的右边的筷子编号为0
Semaphore ChopStick[N]={Semaphore(1),Semaphore(1),Semaphore(1),Semaphore(1),Semaphore(1),Semaphore(1)} ;
void Eating(int Ph_Id)
printf("Philosopher%d: \tI'm eating......\t",(int)Ph_Id);
void Sleeping(int Ph_Id)
printf("Philosopher%d:\tI'm sleeping......\t",(int)Ph_Id);
Sleep(rand()%10000);
void Thinking(int Ph_Id)
printf("Philosopher%d: \tI'm thinking......\t",(int)Ph_Id);
if (pid%2 == 0) //偶数号哲学家
Thinking(pid); //等待中
ChopStick[LEFt(pid)].P(); //先拿起左边的筷子,再拿起右边的筷子
ChopStick[RIGHt(pid)].P();
Eating(pid); //获得的两个信号量则eating
ChopStick[LEFt(pid)].V(); //先后释放左右信号量
ChopStick[RIGHt(pid)].V();
printf("\n");
else if(pid%2==1 ) //奇数号哲学家
Thinking(pid);
ChopStick[RIGHt(pid)].P(); //先拿起右边的筷子,再拿起左边的筷子
ChopStick[LEFt(pid)].P();
Eating(pid); //左右都得到筷子后则eating
ChopStick[RIGHt(pid)].V(); //先后释放右左信号量
ChopStick[LEFt(pid)].V();
printf("\n");
Sleeping(pid); //吃完睡上一会儿
int main(){
HANDLE hPhilosopher[N]; //为每个哲学家分配一个线程
int count =0 ;
for (int Philosopher_id =0 ;Philosopher_id
if(count>5)
break;
::WaitForMultipleObjects(N,hPhilosopher,TRUE,INFINITE);
for (Philosopher_id = 0 ; Philosopher_id
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯