Exercise 9, task 3, solution by Roman ===================================== /* Compile, for example: gcc ex9.c -lpthread -lcurses -oex9.o */ #include #include #include #define PHs 5 //number of Philosophers /* variable sum is shared by the threads */ int sum=0,a; int resources[PHs]; int starv[PHs]={0,0,0,0,0}; char *state[] = {" think ","hungry","|eat| "}; pthread_mutex_t Sem=PTHREAD_MUTEX_INITIALIZER; //Used while printing and sharing sum pthread_mutex_t SemRes=PTHREAD_MUTEX_INITIALIZER; //used for accesing to resources pthread_mutex_t SemRes1[5]; /* thread */ void *runner1(); /* First thread */ main(int argc, char *argv[]) { /* Thread identifier */ pthread_t tid[PHs]; /* Attributes for a thread (stack size, scheduling ...) */ pthread_attr_t attr; /* Set attributes (default attributes are used) */ pthread_attr_init(&attr); //initialization sum=0; initscr(); cbreak();noecho(); clear(); move(12,0); printw("Dining philosophers deadlock free demonstration, please note, the last chopstick is copy of the first one."); printw(" Philosopher always takes both chopsticks only if they both are free.\n"); printw(" Use Ctrl-C to break."); for (a=0;asleep a while starv[myNumber]++; }; { // pthread_mutex_lock(&SemRes1[myNumber]); // pthread_mutex_lock(&SemRes1[(myNumber+1)%PHs]); pthread_mutex_lock(&SemRes); resources[myNumber] =0; resources[(myNumber+1)%PHs]=0; pthread_mutex_unlock(&SemRes); PHtodo=2; //go eat next time } break; case 0: PHtodo=rand_r(&foo)&01; //what to do in the next turn //generates only 0 or 1 think again or be hungry //0 - think again, 1 - hungry break; } pthread_mutex_lock(&Sem); //display state, must be atomic because of curses move(2,myNumber*7+10); printw("%s",state[PHtodo]); move(3,myNumber*7+12); if (PHtodo!=1) printw("%i ", PHtime); else printw(" "); for (i=0;i<=PHs;i++) { //print all sticks, last is copy of the first move(4,(i+1)*7+2); if (resources[i %PHs]==1) printw("|"); else printw(" ") ; } //for for (i=0;i #include #include #include #include #include #define N 5 pthread_mutex_t chopstick[N]; void* philosopher(void *param); int main() { pthread_t tid[N]; int i; for (i = 0; i < N; i++) if (pthread_mutex_init(&chopstick[i], NULL) != 0) { perror("pthread_mutex_init()\n"); exit(-1); } for (i = 0; i < N; i++) if (pthread_create(&tid[i], NULL, philosopher, (void*) i) != 0) { perror("pthread_crate()\n"); exit(-1); } pthread_exit(0); } void* philosopher(void *param) { int id; unsigned int seed; int sec; id = (int)param; do { /* think */ seed = id * time(NULL); sec = rand_r(&seed) % 3 + 1; sleep(sec); printf("Philosopher %d: Did thinking %d seconds.\n", id, sec); printf("Philosopher %d: is hungry.\n", id); /* take a chopstick */ if ((id % 2) == 0) { /* even philosopher */ if (pthread_mutex_trylock(&chopstick[id]) == 0) { printf("Philosopher %d: Takes chopstick %d.\n", id, id); } else { printf("Philosopher %d: Waits for chopstick %d.\n", id, id); sec = time(NULL); pthread_mutex_lock(&chopstick[id]); sec = time(NULL) - sec; printf("Philosopher %d: Waited %d seconds. Takes chopstick %d.\n", id, sec, id); } if (pthread_mutex_trylock(&chopstick[(id + 1) % N]) == 0) { printf("Philosopher %d: Takes chopstick %d.\n", id, (id + 1) % N); } else { printf("Philosopher %d: Waits for chopstick %d.\n", id, (id + 1) % N); sec = time(NULL); pthread_mutex_lock(&chopstick[(id + 1) % N]); sec = time(NULL) - sec; printf("Philosopher %d: Waited %d seconds. Takes chopstick %d.\n", id, sec, (id + 1) % N); } } else { /* odd philosopher */ if (pthread_mutex_trylock(&chopstick[(id + 1) % N]) == 0) { printf("Philosopher %d: Takes chopstick %d.\n", id, (id + 1) % N); } else { printf("Philosopher %d: Waits for chopstick %d.\n", id, (id + 1) % N); sec = time(NULL); pthread_mutex_lock(&chopstick[(id + 1) % N]); sec = time(NULL) - sec; printf("Philosopher %d: Waited %d seconds. Takes chopstick %d.\n", id, sec, (id +1) % N); } if (pthread_mutex_trylock(&chopstick[id]) == 0) { printf("Philosopher %d: Takes chopstick %d.\n", id, id); } else { printf("Philosopher %d: Waits for chopstick %d.\n", id, id); sec = time(NULL); pthread_mutex_lock(&chopstick[id]); sec = time(NULL) - sec; printf("Philosopher %d: Waited %d seconds. Takes chopstick %d.\n", id, sec, id); } } /* eat */ seed = id * time(NULL); sec = rand_r(&seed) % 3 + 1; sleep(sec); printf("Philosopher %d: Ate %d seconds.\n", id, sec); /* put chopstick */ pthread_mutex_unlock(&chopstick[id]); printf("Philosopher %d: Puts chopstick %d.\n", id, id); pthread_mutex_unlock(&chopstick[(id + 1) % N]); printf("Philosopher %d: Puts chopstick %d.\n", id, (id + 1) % N); } while(1); pthread_exit(0); }