#include <semaphore.
h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#define N 5 // Number of philosophers
#define THINKING 0
#define HUNGRY 1
#define EATING 2
sem_t mutex; // Mutex for critical section
sem_t S[N]; // Semaphores for each philosopher
int state[N];
int phil_num[N] = {0, 1, 2, 3, 4};
void* philosopher(void* num);
void take_fork(int);
void put_fork(int);
void test(int);
int main() {
pthread_t thread_id[N];
sem_init(&mutex, 0, 1); // Initialize mutex
for (int i = 0; i < N; i++)
sem_init(&S[i], 0, 0); // Initialize semaphores for each philosopher
// Create philosopher threads
for (int i = 0; i < N; i++) {
pthread_create(&thread_id[i], NULL, philosopher, &phil_num[i]);
printf("Philosopher %d is thinking\n", i + 1);
}
// Wait for all threads to finish
for (int i = 0; i < N; i++) {
pthread_join(thread_id[i], NULL);
}
return 0;
}
void* philosopher(void* num) {
int* i = num;
while (1) {
take_fork(*i); // Try to take forks
sleep(1);
put_fork(*i); // Put down the forks
}
}
void take_fork(int ph_num) {
sem_wait(&mutex);
state[ph_num] = HUNGRY;
printf("Philosopher %d is hungry\n", ph_num + 1);
test(ph_num);
sem_post(&mutex);
sem_wait(&S[ph_num]);
}
void test(int ph_num) {
int left = (ph_num + 4) % N;
int right = (ph_num + 1) % N;
if (state[ph_num] == HUNGRY && state[left] != EATING && state[right]
!= EATING) {
state[ph_num] = EATING;
printf("Philosopher %d is eating\n", ph_num + 1);
sem_post(&S[ph_num]);
}
}
void put_fork(int ph_num) {
sem_wait(&mutex);
state[ph_num] = THINKING;
printf("Philosopher %d is thinking\n", ph_num + 1);
test((ph_num + 4) % N); // Test left neighbor
test((ph_num + 1) % N); // Test right neighbor
sem_post(&mutex);
}