Dining Philosophers Problem in C and C++

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.

Dining Philosophers Problem

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++.

 

17 thoughts on “Dining Philosophers Problem in C and C++”

  1. The program you have mentioned is for 4 philosophers. Will the same work for 5 or any number of philosophers by changing the value of ‘n’?

    1. It should work for more than 4 as long as you change the value of n when you enter it during the program. There is nothing in the code suggesting it shouldn’t.

      1. dhanush katepalli

        pls give the new program this is not working at all and also soo…. complicated .this code is like shit pls change the code

  2. None of your programs have worked for me. Everything has tiny erorrs. I don’t know why this is happening but it does. Hope you can fix it

  3. pls give the new program this is not working at all and also soo…. complicated .this code is like shit pls change the code

  4. very nice program , but was moving too fast Have added some Sleep time so that each action of the philosopher may be see on the run time as it executes with a delay, No other changes have been made
    and the program has been compiled in visual c++

    // philosophers.cpp : This file contains the ‘main’ function. Program execution begins and ends there.
    //

    #include “pch.h”
    #include
    #include
    #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";
    for (int i = 0; i < 10; i++) { cout <“; Sleep(480); }
    }

    //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;
    for (int i = 0; i < 10; i++) { cout << "."; Sleep(180); }
    cout<<"Fork "<<philID+1<<" taken by Philosopher "<<philID+1<<"\n";

    }else{
    for (int i = 0; i < 40; i++) { cout << "."; Sleep(180); }
    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);
    for (int i = 0; i < 30; i++) { cout << "."; Sleep(180); }
    cout<<"\nTill now num of philosophers completed dinner are "<<compltedPhilo<<"\n\n";
    }

    return 0;
    }

  5. Every Philosopher can access forks only to its right and left, since the solution of The Dining Philosophers Problem says to reverse the fork picking of the last Philosopher(in this case P4) so by doing so F4 has not been taken. Now in your first iteration it says Fork 4 taken by P1 but thats simply not possible because P1 can access only F1 & F2.

Leave a Comment

Your email address will not be published. Required fields are marked *