#include #include #include #include #include #include #include #include #include #include #define N 5 #define THINKING 0 #define HUNGRY 1 #define EATING 2 #define LEFT ( i + N - 1) % N #define RIGHT ( i + 1 ) % N pthread_t p1, p2, c1, c2, c3; // uchwyty do watkow volatile int index_filozofa; int state[N]; sem_t *mutex; sem_t *stol[N]; sem_t *tworzenie_filozofow_mutex; void handler(int sig); void take_forks(int i, int id); void put_forks(int i); void test(int i); void *filozof(); void filozofowanie(int id, int i); void think(int id); void eat(int id); void *filozof() { int id = (rand() + 23) % 15; // tylko na potrzeby parametryzowania zmienna index_filozofa sem_wait(tworzenie_filozofow_mutex); sem_post(tworzenie_filozofow_mutex); filozofowanie(id, index_filozofa); } void filozofowanie(int id, int i) { while (1) { think(id); take_forks(i, id); eat(id); put_forks(i); } } void take_forks(int i, int id) { sem_wait(mutex); state[i] = HUNGRY; printf("Filozof: %d głodny\n", id); test(i); sem_post(mutex); sem_wait(stol[i]); } void put_forks(int i) { sem_wait(mutex); state[i] = THINKING; test(LEFT); test(RIGHT); sem_post(mutex); } void test(int i) { if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING) { state[i] = EATING; sem_post(stol[i]); } } void think(int id) { int sec = rand() % 3; printf("Filozof: %d myśli przez %d sekund\n", id, sec); sleep(sec); printf("Filozof: %d przestał myśleć\n", id); } void eat(int id) { int sec = rand() % 5; printf("Filozof: %d zajada sie przez %d sekund\n", id, sec); sleep(sec); printf("Filozof: %d przestał jesc\n", id); } int main() { int i; char *sems[5]; srand(time(NULL)); // nazwy dla filozofow, nie robione automatycznie bo za duzo roboty w porownaniu do zysku ze sklejaniem i zapamietywaniem stringow z liczbami w C sems[0] = "a1"; sems[1] = "b1"; sems[2] = "c1"; sems[3] = "d1"; sems[4] = "e1"; index_filozofa = 0; signal(SIGINT, handler); if ((mutex = sem_open ("/filomutex", O_CREAT, 0660, 1)) == SEM_FAILED) { perror ("sem_czytania sem_open"); exit (1); } if ((tworzenie_filozofow_mutex = sem_open("/tworzeniefilo", O_CREAT, 0660, 1)) == SEM_FAILED) { perror("filozofowie sem_open"); exit(1); } // mutex na aktualizacje zmiennej liczba_czytelnikow for (i = 0; i < 5; ++i) { if ((stol[i] = sem_open (sems[i], O_CREAT, 0660, 1)) == SEM_FAILED) { perror ("/sstol sem_open"); exit (1); } } sem_wait(tworzenie_filozofow_mutex); pthread_create(&p1, NULL, filozof, NULL); ++index_filozofa; pthread_create(&p2, NULL, filozof, NULL); ++index_filozofa; pthread_create(&c1, NULL, filozof, NULL); ++index_filozofa; pthread_create(&c2, NULL, filozof, NULL); ++index_filozofa; pthread_create(&c3, NULL, filozof, NULL); sem_post(tworzenie_filozofow_mutex); pthread_join(p1, NULL); pthread_join(p2, NULL); pthread_join(c1, NULL); pthread_join(c2, NULL); pthread_join(c3, NULL); sem_close(tworzenie_filozofow_mutex); sem_close(mutex); for (i = 0; i < 5; ++i) { sem_close(stol[i]); sem_unlink(sems[i]); sem_destroy(stol[i]); } sem_unlink("/tworzeniefilo"); sem_unlink("/filomutex"); sem_destroy(tworzenie_filozofow_mutex); sem_destroy(mutex); return 0; } void handler(int sig) { pthread_cancel(p1); pthread_cancel(p2); pthread_cancel(c1); pthread_cancel(c2); pthread_cancel(c3); }