In this tutorial you will learn about Dining Philosophers Problem in C and C++ with program example.
What is Dining Philosophers Problem?
There are some Philosophers whose work is just thinking and eating. Let there are 5 (for example) philosophers. They sat at a round table for dinner. To complete dinner each must need two Forks (spoons). But there are only 5 Forks available (Forks always equal to no. of Philosophers) on table. They take in such a manner that, first take left Fork and next right Fork. But problem is they try to take at same time. Since they are trying at same time, Fork 1, 2, 3, 4, 5 taken by Philosopher 1, 2, 3, 4, 5 respectively (since they are left side of each). And each one tries to ta ke right side Fork. But no one found available Fork. And also that each one thinks that someone will release the Fork and then I can eat. This continuous waiting leads to Dead Lock situation.
Also Read: Banker’s Algorithm in C
Dining Arrangement
Solution: To solve this Dead Lock situation, Last philosopher (any one can do this) first try to take right side fork and then left side fork. i.e in our example 5th person tries to take 4th Fork instead of 5th one. Since 4th Fork already taken by 4th the person, he gets nothing. But he left 5th Fork. Now the first person will take this 5th Fork and complete dinner and make 1st and 5th available for remaining people. Next 2nd person takes 1st fork and completes and releases 1st and 2nd. This continuous until all finishes dinner.
Operating System
In Operating System, this concept used in process synchronization. Same problem but instead of Philosophers processes are there and instead of Forks Resources are there. We follow above solution to avoid dead lock condition.
Program for Dining Philosophers Problem in C
#include<stdio.h> #define n 4 int compltedPhilo = 0,i; struct fork{ int taken; }ForkAvil[n]; struct philosp{ int left; int right; }Philostatus[n]; void goForDinner(int philID){ //same like threads concept here cases implemented if(Philostatus[philID].left==10 && Philostatus[philID].right==10) printf("Philosopher %d completed his dinner\n",philID+1); //if already completed dinner else if(Philostatus[philID].left==1 && Philostatus[philID].right==1){ //if just taken two forks printf("Philosopher %d completed his dinner\n",philID+1); Philostatus[philID].left = Philostatus[philID].right = 10; //remembering that he completed dinner by assigning value 10 int otherFork = philID-1; if(otherFork== -1) otherFork=(n-1); ForkAvil[philID].taken = ForkAvil[otherFork].taken = 0; //releasing forks printf("Philosopher %d released fork %d and fork %d\n",philID+1,philID+1,otherFork+1); compltedPhilo++; } else if(Philostatus[philID].left==1 && Philostatus[philID].right==0){ //left already taken, trying for right fork if(philID==(n-1)){ if(ForkAvil[philID].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION ForkAvil[philID].taken = Philostatus[philID].right = 1; printf("Fork %d taken by philosopher %d\n",philID+1,philID+1); }else{ printf("Philosopher %d is waiting for fork %d\n",philID+1,philID+1); } }else{ //except last philosopher case int dupphilID = philID; philID-=1; if(philID== -1) philID=(n-1); if(ForkAvil[philID].taken == 0){ ForkAvil[philID].taken = Philostatus[dupphilID].right = 1; printf("Fork %d taken by Philosopher %d\n",philID+1,dupphilID+1); }else{ printf("Philosopher %d is waiting for Fork %d\n",dupphilID+1,philID+1); } } } else if(Philostatus[philID].left==0){ //nothing taken yet if(philID==(n-1)){ if(ForkAvil[philID-1].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION ForkAvil[philID-1].taken = Philostatus[philID].left = 1; printf("Fork %d taken by philosopher %d\n",philID,philID+1); }else{ printf("Philosopher %d is waiting for fork %d\n",philID+1,philID); } }else{ //except last philosopher case if(ForkAvil[philID].taken == 0){ ForkAvil[philID].taken = Philostatus[philID].left = 1; printf("Fork %d taken by Philosopher %d\n",philID+1,philID+1); }else{ printf("Philosopher %d is waiting for Fork %d\n",philID+1,philID+1); } } }else{} } int main(){ for(i=0;i<n;i++) ForkAvil[i].taken=Philostatus[i].left=Philostatus[i].right=0; while(compltedPhilo<n){ /* Observe here carefully, while loop will run until all philosophers complete dinner Actually problem of deadlock occur only thy try to take at same time This for loop will say that they are trying at same time. And remaining status will print by go for dinner function */ for(i=0;i<n;i++) goForDinner(i); printf("\nTill now num of philosophers completed dinner are %d\n\n",compltedPhilo); } return 0; }
Output
Fork 1 taken by Philosopher 1
Fork 2 taken by Philosopher 2
Fork 3 taken by Philosopher 3
Philosopher 4 is waiting for fork 3
Till now num of philosophers completed dinner are 0
Fork 4 taken by Philosopher 1
Philosopher 2 is waiting for Fork 1
Philosopher 3 is waiting for Fork 2
Philosopher 4 is waiting for fork 3
Till now num of philosophers completed dinner are 0
Philosopher 1 completed his dinner
Philosopher 1 released fork 1 and fork 4
Fork 1 taken by Philosopher 2
Philosopher 3 is waiting for Fork 2
Philosopher 4 is waiting for fork 3
Till now num of philosophers completed dinner are 1
Philosopher 1 completed his dinner
Philosopher 2 completed his dinner
Philosopher 2 released fork 2 and fork 1
Fork 2 taken by Philosopher 3
Philosopher 4 is waiting for fork 3
Till now num of philosophers completed dinner are 2
Philosopher 1 completed his dinner
Philosopher 2 completed his dinner
Philosopher 3 completed his dinner
Philosopher 3 released fork 3 and fork 2
Fork 3 taken by philosopher 4
Till now num of philosophers completed dinner are 3
Philosopher 1 completed his dinner
Philosopher 2 completed his dinner
Philosopher 3 completed his dinner
Fork 4 taken by philosopher 4
Till now num of philosophers completed dinner are 3
Philosopher 1 completed his dinner
Philosopher 2 completed his dinner
Philosopher 3 completed his dinner
Philosopher 4 completed his dinner
Philosopher 4 released fork 4 and fork 3
Till now num of philosophers completed dinner are 4
Program for Dining Philosophers Problem in C++
#include<iostream> #define n 4 using namespace std; int compltedPhilo = 0,i; struct fork{ int taken; }ForkAvil[n]; struct philosp{ int left; int right; }Philostatus[n]; void goForDinner(int philID){ //same like threads concept here cases implemented if(Philostatus[philID].left==10 && Philostatus[philID].right==10) cout<<"Philosopher "<<philID+1<<" completed his dinner\n"; //if already completed dinner else if(Philostatus[philID].left==1 && Philostatus[philID].right==1){ //if just taken two forks cout<<"Philosopher "<<philID+1<<" completed his dinner\n"; Philostatus[philID].left = Philostatus[philID].right = 10; //remembering that he completed dinner by assigning value 10 int otherFork = philID-1; if(otherFork== -1) otherFork=(n-1); ForkAvil[philID].taken = ForkAvil[otherFork].taken = 0; //releasing forks cout<<"Philosopher "<<philID+1<<" released fork "<<philID+1<<" and fork "<<otherFork+1<<"\n"; compltedPhilo++; } else if(Philostatus[philID].left==1 && Philostatus[philID].right==0){ //left already taken, trying for right fork if(philID==(n-1)){ if(ForkAvil[philID].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION ForkAvil[philID].taken = Philostatus[philID].right = 1; cout<<"Fork "<<philID+1<<" taken by philosopher "<<philID+1<<"\n"; }else{ cout<<"Philosopher "<<philID+1<<" is waiting for fork "<<philID+1<<"\n"; } }else{ //except last philosopher case int dupphilID = philID; philID-=1; if(philID== -1) philID=(n-1); if(ForkAvil[philID].taken == 0){ ForkAvil[philID].taken = Philostatus[dupphilID].right = 1; cout<<"Fork "<<philID+1<<" taken by Philosopher "<<dupphilID+1<<"\n"; }else{ cout<<"Philosopher "<<dupphilID+1<<" is waiting for Fork "<<philID+1<<"\n"; } } } else if(Philostatus[philID].left==0){ //nothing taken yet if(philID==(n-1)){ if(ForkAvil[philID-1].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION ForkAvil[philID-1].taken = Philostatus[philID].left = 1; cout<<"Fork "<<philID<<" taken by philosopher "<<philID+1<<"\n"; }else{ cout<<"Philosopher "<<philID+1<<" is waiting for fork "<<philID<<"\n"; } }else{ //except last philosopher case if(ForkAvil[philID].taken == 0){ ForkAvil[philID].taken = Philostatus[philID].left = 1; cout<<"Fork "<<philID+1<<" taken by Philosopher "<<philID+1<<"\n"; }else{ cout<<"Philosopher "<<philID+1<<" is waiting for Fork "<<philID+1<<"\n"; } } }else{} } int main(){ for(i=0;i<n;i++) ForkAvil[i].taken=Philostatus[i].left=Philostatus[i].right=0; while(compltedPhilo<n){ /* Observe here carefully, while loop will run until all philosophers complete dinner Actually problem of deadlock occur only thy try to take at same time This for loop will say that they are trying at same time. And remaining status will print by go for dinner function */ for(i=0;i<n;i++) goForDinner(i); cout<<"\nTill now num of philosophers completed dinner are "<<compltedPhilo<<"\n\n"; } return 0; }
Comment below if you have queries or found any information incorrect in above tutorial for dining philosophers problem in C and C++.
The post Dining Philosophers Problem in C and C++ appeared first on The Crazy Programmer.