Practical-11
Title : Develop program to implement solution for the dining philosopher's Problem using threads.
—----------------------------------------------------------------------------------------------------------------------------
The Dining Philosophers Problem is a classic synchronization problem that involves a certain number of philosophers sitting at a table with a fork between each pair of adjacent philosophers. The goal is to ensure that no philosopher will starve and that all can eat without deadlock or resource contention.
Algorithm for Dining Philosophers Problem
Initialization:
Define Constants:
NUM_PHILOSOPHERS: Number of philosophers (and forks).
forks[]: Array of mutexes, one for each fork.
Initialize Mutexes:
For each fork, initialize a mutex in the forks[] array.
Initialize a mutex for printing to avoid jumbled output.
Philosopher Process:
Repeat indefinitely:
Think:
Print a message indicating the philosopher is thinking.
Simulate thinking (e.g., sleep for a random duration).
Pick Up Forks:
Determine the indices of the left and right forks:
left_fork = philosopher_index
right_fork = (philosopher_index + 1) % NUM_PHILOSOPHERS
Lock Left Fork:
Acquire the mutex for the left fork.
Lock Right Fork:
Acquire the mutex for the right fork.
Eat:
Print a message indicating the philosopher is eating.
Simulate eating (e.g., sleep for a random duration).
Put Down Forks:
Unlock Right Fork:
Release the mutex for the right fork.
Unlock Left Fork:
Release the mutex for the left fork.
Main Procedure:
Initialize Mutexes:
Initialize all fork mutexes and the printing mutex.
Create Philosopher Threads:
For each philosopher, create a thread that runs the philosopher process.
Join Threads:
Wait for all philosopher threads to finish (though in practice, these threads run indefinitely).
Destroy Mutexes:
Clean up and destroy all mutexes used.
Code :
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#define NUM_PHILOSOPHERS 5
// Mutexes for forks
pthread_mutex_t forks[NUM_PHILOSOPHERS];
// Mutex for printing (to avoid jumbled output)
pthread_mutex_t print_mutex;
// Function prototypes
void* philosopher(void* num);
void think(int philosopher);
void eat(int philosopher);
int main() {
pthread_t philosophers[NUM_PHILOSOPHERS];
int philosopher_nums[NUM_PHILOSOPHERS];
// Initialize mutexes for forks
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_mutex_init(&forks[i], NULL);
}
// Initialize mutex for printing
pthread_mutex_init(&print_mutex, NULL);
// Create philosopher threads
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
philosopher_nums[i] = i;
pthread_create(&philosophers[i], NULL, philosopher, &philosopher_nums[i]);
}
// Wait for all philosopher threads to finish
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_join(philosophers[i], NULL);
}
// Destroy mutexes
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_mutex_destroy(&forks[i]);
}
pthread_mutex_destroy(&print_mutex);
return 0;
}
void* philosopher(void* num) {
int philosopher = *(int*)num;
while (1) {
think(philosopher);
// Determine the indices of the forks
int left_fork = philosopher;
int right_fork = (philosopher + 1) % NUM_PHILOSOPHERS;
// Try to pick up left fork
pthread_mutex_lock(&forks[left_fork]);
// Try to pick up right fork
pthread_mutex_lock(&forks[right_fork]);
// Eating
eat(philosopher);
// Put down right fork
pthread_mutex_unlock(&forks[right_fork]);
// Put down left fork
pthread_mutex_unlock(&forks[left_fork]);
}
return NULL;
}
void think(int philosopher) {
pthread_mutex_lock(&print_mutex);
printf("Philosopher %d is thinking.\n", philosopher);
pthread_mutex_unlock(&print_mutex);
sleep(1); // Simulate thinking
}
void eat(int philosopher) {
pthread_mutex_lock(&print_mutex);
printf("Philosopher %d is eating.\n", philosopher);
pthread_mutex_unlock(&print_mutex);
sleep(1); // Simulate eating
}
No comments:
Post a Comment