Advertisement
Guest User

Untitled

a guest
Jun 20th, 2018
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.43 KB | None | 0 0
  1. #include <pthread.h>
  2. #include <semaphore.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5.  
  6. #define READERS 5 // liczba czytelnikĂłw
  7.  
  8. /*
  9. * - mutex: zapewnia wyłączny dostęp do biblioteki albo czytelnikom albo
  10. * pisarzowi
  11. * - mutex_readers: w rozwiązaniu trzeba wiedzieć czy dany czytelnik jest
  12. * pierwszym wchodzącym lub ostatnim wychodzącym by wykonać wtedy dodatkowe
  13. * operacje. Ten mutex zapewnia, że sprawdzenie to wykona się poprawnie (nie
  14. * będzie sytuacji, że dwóch lub więcej czytelników uzna siebie jednocześnie
  15. * za "pierwszego" lub "ostatniego" czytelnika.
  16. * - mutex_order: zapewnia cechę kolejkowania tak aby nie doszło do zagłodzenia
  17. * czytelnikĂłw lub pisarza
  18. */
  19. pthread_mutex_t mutex, mutex_readers, mutex_order;
  20. sem_t sem_readers; // licznik czytelnikĂłw
  21.  
  22. /*
  23. * Kod symulujący czytanie (krótka operacja)
  24. */
  25. void read_content(int id) {
  26. printf("Reading (id=%d)\n", id);
  27. }
  28.  
  29. /*
  30. * Kod symulujący pisanie (wymuszona, długa operacja)
  31. */
  32. void write_content() {
  33. int i;
  34. printf("Writing");
  35. fflush(NULL);
  36. for (i = 0; i < 3; ++i) {
  37. sleep(1);
  38. printf(".");
  39. fflush(NULL);
  40. }
  41. printf("\n");
  42. }
  43.  
  44. /*
  45. * Kod kaĹźdego czytelnika.
  46. */
  47. void *reader(void *id) {
  48. while (1) {
  49. int readers;
  50.  
  51. pthread_mutex_lock(&mutex_order);
  52. pthread_mutex_lock(&mutex_readers);
  53. sem_getvalue(&sem_readers, &readers);
  54. if (readers == 0) // jeśli pierwszy czytelnik
  55. pthread_mutex_lock(&mutex); // to zablokuj bibliotekę
  56. sem_post(&sem_readers); // zwiększ licznik czytelników
  57. pthread_mutex_unlock(&mutex_order);
  58. pthread_mutex_unlock(&mutex_readers);
  59.  
  60. read_content((int) id); // akcja czytania
  61.  
  62. pthread_mutex_lock(&mutex_readers);
  63. sem_wait(&sem_readers);
  64. sem_getvalue(&sem_readers, &readers);
  65. if (readers == 0) // jeśli ostatni czytelnik
  66. pthread_mutex_unlock(&mutex); // to zwolnij bibliotekę
  67. pthread_mutex_unlock(&mutex_readers);
  68. }
  69. }
  70.  
  71. /*
  72. * Kod pisarza bardzo przypomina kod producenta. Dodano jedynie "mutex_order"
  73. * celem zapewnienia cechy kolejkowania żądań dostępu do biblioteki.
  74. */
  75. void *writer(void *dummy) {
  76. while (1) {
  77. pthread_mutex_lock(&mutex_order);
  78. pthread_mutex_lock(&mutex);
  79. pthread_mutex_unlock(&mutex_order);
  80. write_content();
  81. pthread_mutex_unlock(&mutex);
  82. }
  83. }
  84.  
  85. int main() {
  86. int i;
  87.  
  88. pthread_attr_t attr;
  89. pthread_attr_init(&attr);
  90. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  91.  
  92. pthread_mutex_init(&mutex, NULL);
  93. pthread_mutex_init(&mutex_readers, NULL);
  94. pthread_mutex_init(&mutex_order, NULL);
  95. sem_init(&sem_readers, 0, 0);
  96.  
  97. pthread_t threads[2];
  98. pthread_create(&threads[0], &attr, writer, NULL);
  99. for (i = 1; i <= READERS; ++i)
  100. pthread_create(&threads[i], &attr, reader, (void*) i);
  101.  
  102. for (i = 0; i <= READERS + 1; ++i)
  103. pthread_join(threads[i], NULL);
  104.  
  105. pthread_attr_destroy(&attr);
  106. pthread_mutex_destroy(&mutex);
  107. pthread_mutex_destroy(&mutex_readers);
  108. pthread_mutex_destroy(&mutex_order);
  109. sem_destroy(&sem_readers);
  110.  
  111. pthread_exit(NULL);
  112. return 0;
  113. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement