Skip to content

Instantly share code, notes, and snippets.

@radito3
Last active May 23, 2020 15:22
Show Gist options
  • Save radito3/a7ec7d15a013473a09e2fc7521970293 to your computer and use it in GitHub Desktop.
Save radito3/a7ec7d15a013473a09e2fc7521970293 to your computer and use it in GitHub Desktop.
C program for an Arbitrator solution to the Dining Philosophers synchronization problem
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#define N 5
#define LEFT(X) ((X) + 4) % N
#define RIGHT(X) ((X) + 1) % N
typedef enum { EATING, HUNGRY, THINKING } ph_states;
ph_states states[N];
//arbitrator
pthread_mutex_t lock = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
sem_t forks[N];
void try_eat(int th_num) {
if (states[th_num] == HUNGRY &&
states[LEFT(th_num)] != EATING &&
states[RIGHT(th_num)] != EATING) {
states[th_num] = EATING;
sleep(2);
printf("Philosopher %d takes fork %d and %d\n", th_num + 1, LEFT(th_num) + 1, th_num + 1);
printf("Philosopher %d is Eating\n", th_num + 1);
sem_post(&forks[th_num]);
}
}
void become_hungry(int th_num) {
pthread_mutex_lock(&lock);
states[th_num] = HUNGRY;
printf("Philosopher %d is Hungry\n", th_num + 1);
// eat if neighbours are not eating
try_eat(th_num);
pthread_mutex_unlock(&lock);
// if unable to eat wait to be signalled
sem_wait(&forks[th_num]);
sleep(1);
}
void think(int th_num) {
pthread_mutex_lock(&lock);
states[th_num] = THINKING;
printf("Philosopher %d putting fork %d and %d down\n", th_num + 1, LEFT(th_num) + 1, th_num + 1);
printf("Philosopher %d is thinking\n", th_num + 1);
try_eat(LEFT(th_num));
try_eat(RIGHT(th_num));
pthread_mutex_unlock(&lock);
}
void *philosopher_work(void *arg) {
int th_num = *(int *) arg;
while (1) {
sleep(1);
become_hungry(th_num);
sleep(1);
think(th_num);
}
return NULL;
}
int main() {
int i;
pthread_t thread_id[N];
int phil[N] = {0, 1, 2, 3, 4};
for (i = 0; i < N; i++) {
sem_init(&forks[i], 0, 0);
}
for (i = 0; i < N; i++) {
pthread_create(&thread_id[i], NULL, philosopher_work, &phil[i]);
printf("Philosopher %d is thinking\n", i + 1);
}
for (i = 0; i < N; i++) {
pthread_join(thread_id[i], NULL);
}
pthread_mutex_destroy(&lock);
for (i = 0; i < N; i++) {
sem_destroy(&forks[i]);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment