Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Classical synchronization problem:
- * Problem is summarised as 5 philosophers sitting at a round table doing 2 things, eating and thinking.
- * While eating they are not thinking and while thinking they are not eating.
- * Each philosophers have plates, that is 5 plates.
- * And there is fork places between each pair of adjacent philosophers, that is total of 5 forks.
- * Each philosopher need 2 forks to eat.
- * Each philosopher can only use the forks on his immediate left and immediate right.
- * Our goal is to prevent resource starvation:
- * let them interchange eating and thinking.
- * Avoid deadlocks
- * solution is important in: OS's kernel, money transfer and other areas
- *
- * Our assumptions: all philosophers think after creation, then someone gets hungry:
- * HUNGRY -> (EATING -> THINKING)
- * or HUNGRY -> should wait
- *
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <semaphore.h>
- #include <pthread.h>
- #include <unistd.h>
- // we have 5 philosophers total
- #define PhilosophersCount 5
- // define states of the philosophers:
- #define THINKING 0
- #define HUNGRY 1
- #define EATING 2
- // define neighbors of each philosopher
- #define GET_LEFT_NEIGHBOUR (ph_num + 4) % PhilosophersCount
- #define GET_RIGHT_NEIGHBOUR (ph_num + 1) % PhilosophersCount
- sem_t mutex;
- // array of semaphores for each fork
- sem_t fork_smph[PhilosophersCount];
- // array of each philosopher's states: [ {0 or 1 or 2},..,..,.., {0 or 1 or 2} ]
- int state [PhilosophersCount];
- // sequence of philosophers from the 0th to the 4th
- int philosophers [PhilosophersCount] = {0, 1, 2, 3, 4};
- void tryToEat(int ph_num)
- {
- // checking philosopher's state and his neighbors
- if (
- state[ph_num] == HUNGRY &&
- state[GET_LEFT_NEIGHBOUR] != EATING &&
- state[GET_RIGHT_NEIGHBOUR] != EATING
- )
- {
- // change state into EATING
- state[ph_num] = EATING;
- sleep(2);
- printf("Philosopher %d takes fork %d and %d\n", ph_num + 1, GET_LEFT_NEIGHBOUR + 1, ph_num + 1);
- printf("Philosopher %d is Eating\n", ph_num + 1);
- sem_post(&fork_smph[ph_num]); // sem_post() unlocks the semaphore
- }
- else
- {
- printf ("Philosopher %d should wait\n", ph_num + 1);
- }
- }
- void take_fork(int ph_num)
- {
- sem_wait(&mutex); // performing a semaphore lock operation
- state[ph_num] = HUNGRY; // changing state
- printf("Philosopher %d is Hungry\n", ph_num + 1 );
- tryToEat(ph_num);
- sem_post(&mutex);
- sem_wait(&fork_smph[ph_num]);
- sleep(1);
- }
- void put_fork(int ph_num)
- {
- sem_wait(&mutex);
- state[ph_num] = THINKING; // changing state
- printf("Philosopher %d putting fork %d and %d down\n", ph_num + 1, GET_LEFT_NEIGHBOUR + 1, ph_num + 1);
- printf("Philosopher %d is thinking\n", ph_num + 1);
- tryToEat(GET_LEFT_NEIGHBOUR);
- tryToEat(GET_RIGHT_NEIGHBOUR);
- sem_post(&mutex);
- }
- void *philospher(void *num)
- {
- while(1)
- {
- int *i = (int*) num;
- sleep(1);
- take_fork(*i);
- sleep(0);
- put_fork(*i);
- }
- return EXIT_SUCCESS;
- }
- int main()
- {
- int i;
- pthread_t threads [PhilosophersCount];
- sem_init(&mutex,0,1);
- for( i = 0; i < PhilosophersCount; i++ )
- sem_init(&fork_smph[i], 0, 0);
- for(i = 0; i < PhilosophersCount; i++)
- {
- pthread_create(&threads[i], NULL, philospher, &philosophers[i]);
- printf("Philosopher %d is thinking\n", i + 1); // their initial state
- }
- for( i = 0; i < PhilosophersCount; i++ )
- pthread_join(threads[i], NULL);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement