Dining Philosophers Problem
Have you ever heard of the dining philosophers problem? If not, let me provide you with a brief explanation.
Imagine five philosophers seated around a table, each with a plate of food and two forks. However, these philosophers are not like ordinary diners; they have a unique way of eating. To enjoy their meal, they need to use two forks simultaneously. This creates a challenge because, in order to eat, a philosopher must acquire the fork held by the philosopher on their left and the one held by the philosopher on their right. Meanwhile, the philosophers are engaged in a cycle of eating, sleeping, and thinking, with each activity dependent on the others.
Now, let’s shift our perspective from philosophers and forks to processes and computer resources. Think of these philosophers as processes and the forks as crucial computer resources. Picture a scenario where a process seeks access to a resource, and simultaneously, another process desires the same resource. This mirrors the dining philosophers' problem, where a philosopher needs a fork to eat, and another philosopher might simultaneously be reaching for that same fork, leading to a potential issue.
Get Anas Bouzanbil’s stories in your inbox
Join Medium for free to get updates from this writer.
To resolve this resource contention, we need to manage these resources more efficiently. In this article, I’ll tackle the Dining Philosophers Problem using the C language, treating each philosopher as a thread. The forks, essential for the philosophers to dine, will be represented as mutexes. However, the complete solution to the dining dilemma will be explored in a subsequent article. For now, our focus lies on understanding threads and mutexes
To create a thread in C, the process is straightforward. In our case, we’ll be working with two threads, representing them as two philosophers. Below is a snippet illustrating how to create threads in C:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void* I_am_the_routine(void* arg) {
int i = *((int*)arg);
printf("I am the philosopher number %d\n", i);
return NULL;
}
int main(void) {
pthread_t *thread = malloc(sizeof(pthread_t) * 2);
int a[2] = {1, 2};
int i = 0;
while (i < 2) {
pthread_create(&thread[i], NULL, I_am_the_routine, &a[i]);
i++;
}
i = 0;
while (i < 2) {
pthread_join(thread[i], NULL);
i++;
}
free(thread);
return 0;
}and congratulations now you have finished creating a thread . now let us create a forks for each philosopher
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef struct {
int sharedInt;
pthread_mutex_t mutex;
} SharedData;
void* philosopher(void* arg) {
SharedData* sharedData = (SharedData*)arg;
while (1) {
pthread_mutex_lock(&(sharedData->mutex));
(sharedData->sharedInt)++;
printf("Philosopher incremented the shared integer to %d\n", sharedData->sharedInt);
pthread_mutex_unlock(&(sharedData->mutex));
}
return NULL;
}
int main(void) {
pthread_t threads[2];
SharedData sharedData;
sharedData.sharedInt = 0;
pthread_mutex_init(&(sharedData.mutex), NULL);
for (int i = 0; i < 2; ++i) {
pthread_create(&threads[i], NULL, philosopher, &sharedData);
}
for (int i = 0; i < 2; ++i) {
pthread_join(threads[i], NULL);
}
pthread_mutex_destroy(&(sharedData.mutex));
return 0;
}This is how you will create mutexes, which represent the forks, and the threads that simulate the philosophers’ actions. Now, you just need to devise the logic to solve this problem. I have already solved this problem, and you can find the solution on my GitHub repository. We will continue discussing this topic in the next article.








