Skip to content

In a house, five philosophers reside and gather around a shared dining table. Each philosopher has a designated place at the table where they dine. Their primary concern, apart from their philosophical pursuits, revolves around a particular dish of spaghetti that requires the use of two forks. There is a fork placed between each plate on the table.

Notifications You must be signed in to change notification settings

MarouanDoulahiane/philosophers

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 

Repository files navigation

Philosophers

I never thought philosophy would be so deadly

Dining philosophers problem's solution for 42 cursus project

Index

  1. General idea
  2. Race Conditions and Mutexes
  3. Step to Step Guide
  4. Utils Functions
The mandatory part of this project asks us to solve the [dining philosophers problem](https://en.wikipedia.org/wiki/Dining_philosophers_problem) and implement a multithreading solution. To better understand the solution, it's recommended to read about threads and multithreading. Another recommendation is to read the subject before starting the project. Now, let's dive into the general idea applied in this project.

Imagine a round table with 'N' philosophers sitting around it, each bringing a fork and placing it to their right. Each philosopher can perform three actions: eat, think, or sleep. However, to eat, a philosopher must pick up two adjacent forks. The challenge lies in organizing the eating actions of the philosophers without hardcoding them to eat separately. Instead, philosophers must organize themselves using mutexes.

A [race condition](https://stackoverflow.com/questions/34510/what-is-a-race-condition) occurs when one or more threads try to access and modify the same variable simultaneously, potentially leading to errors in the final value of that variable. Let's illustrate this with an example:
#include <pthread.h>
#include <stdio.h>

int cont = 0;

void *routine()
{
  int i;
  for (i = 0; i < 1000000; i++)
      cont++;
  return NULL;
}

int main()
{
  pthread_t tid1, tid2;

  pthread_create(&tid1, NULL, &routine, NULL);
  pthread_create(&tid2, NULL, &routine, NULL);

  pthread_join(tid1, NULL);
  pthread_join(tid2, NULL);
  printf("cont: %d\n", cont);
}
In this example, two threads increment a variable cont by 1,000,000. However, due to race conditions, the final value of cont may not be 2,000,000 as expected.

<h3><a name='Mutexes'>Mutexes</a></h3>
Mutexes are locks used to prevent data racing. When a mutex is locked, any thread attempting to lock it will be paused until the mutex is unlocked. In the above example, we could prevent the race condition by adding a lock before incrementing the variable.
c
Copy code
#include <pthread.h>
#include <stdio.h>

int cont = 0;
pthread_mutex_t lock;

void *routine()
{
  int i;
  for (i = 0; i < 1000000; i++) {
    pthread_mutex_lock(&lock);
    cont++;
    pthread_mutex_unlock(&lock);
  }
  return NULL;
}

int main()
{
  pthread_t tid1, tid2;

  pthread_mutex_init(&lock, NULL);
  pthread_create(&tid1, NULL, &routine, NULL);
  pthread_create(&tid2, NULL, &routine, NULL);

  pthread_join(tid1, NULL);
  pthread_join(tid2, NULL);
  pthread_mutex_destroy(&lock);
  printf("cont: %d\n", cont);
}

Remember to initialize and destroy mutexes properly using pthread_mutex_init and pthread_mutex_destroy.

Validate the input parameters, ensuring they are within acceptable ranges. Define structures for storing general data and philosopher-specific data. Make sure to include a pointer to the general data structure within the philosopher structure. Allocate memory for the structures, initialize mutexes, and start threads. Structure the philosopher's routine, supervisor, and monitor threads. Ensure synchronization using mutexes and proper handling of conditions like eating, sleeping, and thinking. Clean up by joining threads, destroying mutexes, and freeing allocated memory. Here are some utility functions you might need for the project:
  • Function to clear all allocated memory.
  • Function to exit the program, clearing all resources.
  • Function to handle errors and exit the program.
  • Function to get the current time in milliseconds.
  • Reimplementation of the `usleep` function for more precise timing.

About

In a house, five philosophers reside and gather around a shared dining table. Each philosopher has a designated place at the table where they dine. Their primary concern, apart from their philosophical pursuits, revolves around a particular dish of spaghetti that requires the use of two forks. There is a fork placed between each plate on the table.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published