-
Notifications
You must be signed in to change notification settings - Fork 0
/
DPP_arbitrator.c
77 lines (60 loc) · 2.12 KB
/
DPP_arbitrator.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
An alternative solution to the
Dining Philosophers problem using an arbitrator.
This way it can be guaranteed that an individual philosopher
can only pick up both or none of the chopsticks.
We can imagine a waiter performing this service.
The waiter gives permission to only one philosopher at a time
until she picks up both chopsticks. Putting down a chopstick
is always allowed. The waiter can be implemented in code as a mutex.
This solution introduces a central entity (arbitrator) and can also
result in reduced parallelism. If one philosopher is eating and
another request a fork, all other philosophers must wait until
this request is fulfilled, even if other chopsticks are still
available to them. */
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM_PHILOSOPHERS 5
sem_t forks[NUM_PHILOSOPHERS];
sem_t arbitrator;
void *philosopher(void *arg) {
int philosopher_id = *(int*) arg;
int left_fork = philosopher_id;
int right_fork = (philosopher_id + 1) % NUM_PHILOSOPHERS;
while (1) {
// Thinking
printf("Philosopher %d is thinking.\n", philosopher_id);
usleep(rand() % 1000000);
// Waiting for forks
sem_wait(&arbitrator);
sem_wait(&forks[left_fork]);
sem_wait(&forks[right_fork]);
// Eating
printf("Philosopher %d is eating.\n", philosopher_id);
usleep(rand() % 1000000);
// Freeing forks
sem_post(&forks[right_fork]);
sem_post(&forks[left_fork]);
// Signaling arbitrator
sem_post(&arbitrator);
}
return NULL;
}
int main() {
srand(time(NULL));
pthread_t philosophers[NUM_PHILOSOPHERS];
int philosopher_ids[NUM_PHILOSOPHERS];
sem_init(&arbitrator, 0, NUM_PHILOSOPHERS - 1);
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
sem_init(&forks[i], 0, 1);
philosopher_ids[i] = i;
pthread_create(&philosophers[i], NULL, philosopher, &philosopher_ids[i]);
}
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_join(philosophers[i], NULL);
}
return 0;
}