Advertisement
Guest User

Dining Philosophers in POSIX C

a guest
Nov 24th, 2015
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.55 KB | None | 0 0
  1. /*
  2.  * Classical synchronization problem:
  3.  * Problem is summarised as 5 philosophers sitting at a round table doing 2 things, eating and thinking.
  4.  * While eating they are not thinking and while thinking they are not eating.
  5.  * Each philosophers have plates, that is 5 plates.
  6.  * And there is fork places between each pair of adjacent philosophers, that is total of 5 forks.
  7.  * Each philosopher need 2 forks to eat.
  8.  * Each philosopher can only use the forks on his immediate left and immediate right.
  9.  * Our goal is to prevent resource starvation:
  10.  * let them interchange eating and thinking.
  11.  * Avoid deadlocks
  12.  * solution is important in: OS's kernel, money transfer and other areas
  13.  *
  14.  * Our assumptions: all philosophers think after creation, then someone gets hungry:
  15.  * HUNGRY -> (EATING -> THINKING)
  16.  * or HUNGRY -> should wait
  17.  *
  18.  */
  19.  
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <semaphore.h>
  23. #include <pthread.h>
  24. #include <unistd.h>
  25.  
  26. // we have 5 philosophers total
  27. #define PhilosophersCount 5
  28.  
  29. // define states of the philosophers:
  30. #define THINKING 0
  31. #define HUNGRY 1
  32. #define EATING 2
  33.  
  34. // define neighbors of each philosopher
  35. #define GET_LEFT_NEIGHBOUR (ph_num + 4) % PhilosophersCount
  36. #define GET_RIGHT_NEIGHBOUR (ph_num + 1) % PhilosophersCount
  37.  
  38. sem_t mutex;
  39.  
  40. // array of semaphores for each fork
  41. sem_t fork_smph[PhilosophersCount];
  42.  
  43. // array of each philosopher's states: [ {0 or 1 or 2},..,..,.., {0 or 1 or 2} ]
  44. int state [PhilosophersCount];
  45.  
  46. // sequence of philosophers from the 0th to the 4th
  47. int philosophers [PhilosophersCount] = {0, 1, 2, 3, 4};
  48.  
  49. void tryToEat(int ph_num)
  50. {
  51.     // checking philosopher's state and his neighbors
  52.     if (
  53.             state[ph_num] == HUNGRY &&
  54.             state[GET_LEFT_NEIGHBOUR] != EATING &&
  55.             state[GET_RIGHT_NEIGHBOUR] != EATING
  56.         )
  57.     {
  58.         // change state into EATING
  59.         state[ph_num] = EATING;
  60.         sleep(2);
  61.  
  62.         printf("Philosopher %d takes fork %d and %d\n", ph_num + 1, GET_LEFT_NEIGHBOUR + 1, ph_num + 1);
  63.         printf("Philosopher %d is Eating\n", ph_num + 1);
  64.  
  65.         sem_post(&fork_smph[ph_num]);  // sem_post() unlocks the semaphore
  66.     }
  67.     else
  68.     {
  69.         printf ("Philosopher %d should wait\n", ph_num + 1);
  70.     }
  71. }
  72.  
  73.  
  74. void take_fork(int ph_num)
  75. {
  76.     sem_wait(&mutex);   // performing a semaphore lock operation
  77.         state[ph_num] = HUNGRY;     // changing state
  78.         printf("Philosopher %d is Hungry\n", ph_num + 1 );
  79.         tryToEat(ph_num);
  80.     sem_post(&mutex);
  81.  
  82.     sem_wait(&fork_smph[ph_num]);
  83.     sleep(1);
  84. }
  85.  
  86.  
  87.  
  88. void put_fork(int ph_num)
  89. {
  90.     sem_wait(&mutex);
  91.         state[ph_num] = THINKING;   // changing state
  92.         printf("Philosopher %d putting fork %d and %d down\n", ph_num + 1, GET_LEFT_NEIGHBOUR + 1, ph_num + 1);
  93.         printf("Philosopher %d is thinking\n", ph_num + 1);
  94.         tryToEat(GET_LEFT_NEIGHBOUR);
  95.         tryToEat(GET_RIGHT_NEIGHBOUR);
  96.     sem_post(&mutex);
  97. }
  98.  
  99. void *philospher(void *num)
  100. {
  101.     while(1)
  102.     {
  103.         int *i = (int*) num;
  104.         sleep(1);
  105.         take_fork(*i);
  106.         sleep(0);
  107.         put_fork(*i);
  108.     }
  109.     return EXIT_SUCCESS;
  110. }
  111.  
  112.  
  113. int main()
  114. {
  115.     int i;
  116.     pthread_t threads [PhilosophersCount];
  117.     sem_init(&mutex,0,1);
  118.     for( i = 0; i < PhilosophersCount; i++ )
  119.         sem_init(&fork_smph[i], 0, 0);
  120.     for(i = 0; i < PhilosophersCount; i++)
  121.     {
  122.         pthread_create(&threads[i], NULL, philospher, &philosophers[i]);
  123.         printf("Philosopher %d is thinking\n", i + 1);      // their initial state
  124.     }
  125.     for( i = 0; i < PhilosophersCount; i++ )
  126.         pthread_join(threads[i], NULL);
  127. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement