#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h> // Include semaphore header
#include <unistd.h>
#define NUM_PHILOSOPHERS 5
sem_t forks[NUM_PHILOSOPHERS]; // Declare semaphore for forks
pthread_mutex_t eatCountMutex = PTHREAD_MUTEX_INITIALIZER;
int eatCount = 0;
void *philosopher(void *arg) {
int id = *(int *)arg;
while (1) {
printf("Philosopher %d is thinking.\n", id
);
printf("Philosopher %d is hungry.\n", id
);
// Pick up the forks (left and right)
sem_wait(&forks[id]); // Left fork
sem_wait(&forks[(id + 1) % NUM_PHILOSOPHERS]); // Right fork
// Eating
printf("Philosopher %d is eating.\n", id
);
// Put down the forks
sem_post(&forks[id]); // Left fork
sem_post(&forks[(id + 1) % NUM_PHILOSOPHERS]); // Right fork
// Track if each philosopher has eaten at least once
pthread_mutex_lock(&eatCountMutex);
eatCount++;
if (eatCount >= NUM_PHILOSOPHERS) {
printf("All philosophers have eaten at least once.\n"); pthread_mutex_unlock(&eatCountMutex);
}
pthread_mutex_unlock(&eatCountMutex);
}
return NULL;
}
int main() {
pthread_t philosophers[NUM_PHILOSOPHERS];
int ids[NUM_PHILOSOPHERS];
// Initialize semaphores
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
ids[i] = i;
sem_init(&forks[i], 0, 1); // Initialize each fork semaphore with value 1
}
// Create philosopher threads
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_create(&philosophers[i], NULL, philosopher, (void *)&ids[i]);
}
// Join philosopher threads
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_join(philosophers[i], NULL);
}
// Destroy semaphores
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
sem_destroy(&forks[i]); // Clean up semaphores
}
return 0;
}