Dining Philosophers Problem in C and C++

In this instructional exercise, you will find out about the Dining Philosophers Problem in C and C++ with the program model.

What is the Dining Philosophers Problem?

There are a few Philosophers whose work is simply thinking and eating. Let there are 5 (for instance) philosophers. They sat at a round table for supper. To finish supper each must need two Forks (spoons).

In any case, there are just 5 Forks accessible (Forks constantly equivalent to no. of Philosophers) on the table.

They take in such a way, that, first take left Fork and next right Fork. In any case, the issue is the attempt to take at the same time. Since they are attempting at the same time, Fork 1, 2, 3, 4, 5 taken by Philosopher 1, 2, 3, 4, 5 separately (since they are left half of each). Also, everyone attempts to take the right side Fork.

Dining Philosophers Problem in C and C++

Be that as it may, nobody discovered accessible Fork. And furthermore that everyone imagines that somebody will discharge the Fork and afterwards I can eat. This constant holding up prompts Dead Lock circumstance.

Dining Arrangement

Arrangement: To understand this Dead Lock circumstance, Last savant (anyone can do this) first attempt to take right side fork and afterwards left side fork.

i.e in our model fifth individual attempts to take fourth Fork rather than the fifth one. Since the fourth Fork previously taken by fourth the individual, he gets nothing. Be that as it may, he left fifth Fork.

Presently the primary individual will take this fifth Fork and complete supper and make first and fifth accessible for outstanding individuals. Next second individual takes the first fork and finishes and discharges first and second. This constant until all completions supper.

Working System

#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;
}

In the Operating System, this idea utilized in process synchronization. The same issue yet rather than Philosophers procedures are there and rather than Forks Resources are there. We pursue the above answer to maintain a strategic distance from gridlock condition.

Remark underneath in the event that you have questions or discover any data off base in above instructional exercise for dining philosophers issue in C and C++.

Here’s a Video Tutorial for you, from this easy tutorial you will be able to understand the coding Easily!

Leave a Comment

error: Alert: Content is protected!!