Advertisement
Guest User

lab8asc

a guest
Apr 25th, 2017
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.57 KB | None | 0 0
  1. /**
  2. * SO, 2016
  3. * Lab #8
  4. *
  5. * Task #7, lin
  6. *
  7. */
  8. #include <pthread.h>
  9. #include <unistd.h>
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14.  
  15. #include <utils.h>
  16.  
  17. #define BUFFER_SIZE 5
  18. #define NR_ITERATIONS 30
  19.  
  20. typedef struct {
  21. int buff[BUFFER_SIZE];
  22. int count;
  23. } buffer_t;
  24.  
  25.  
  26. void init_buffer(buffer_t *b)
  27. {
  28. memset(b->buff, 0, sizeof(int) * BUFFER_SIZE);
  29. b->count = 0;
  30. }
  31.  
  32. void insert_item(buffer_t *b, int item)
  33. {
  34. b->buff[b->count] = item;
  35. b->count++;
  36. }
  37.  
  38. int remove_item(buffer_t *b)
  39. {
  40. b->count--;
  41. return b->buff[b->count];
  42. }
  43.  
  44. int is_buffer_full(buffer_t *b)
  45. {
  46. return b->count == BUFFER_SIZE;
  47. }
  48.  
  49. int is_buffer_empty(buffer_t *b)
  50. {
  51. return b->count == 0;
  52. }
  53.  
  54. /* the buffer where the producer will place items
  55. * and from which the consumer will take items
  56. */
  57. buffer_t common_area;
  58.  
  59. pthread_cond_t buffer_not_full = PTHREAD_COND_INITIALIZER;
  60. pthread_cond_t buffer_not_empty = PTHREAD_COND_INITIALIZER;
  61.  
  62. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  63.  
  64. void *producer_fn(void *arg)
  65. {
  66. int item_to_insert, i, rc;
  67.  
  68. for (i = 0; i < NR_ITERATIONS; i++) {
  69. item_to_insert = rand() % 100;
  70.  
  71. rc = pthread_mutex_lock(&mutex);
  72. DIE(rc != 0, "pthread_mutex_lock");
  73.  
  74. while (is_buffer_full(&common_area)) {
  75. /* we want to produce so we must
  76. * wait for the buffer not to be full
  77. */
  78. rc = pthread_cond_wait(&buffer_not_full, &mutex);
  79. DIE(rc != 0, "pthread_cond_wait");
  80. }
  81.  
  82. insert_item(&common_area, item_to_insert);
  83.  
  84. printf("Inserted item %d\n", item_to_insert);
  85.  
  86. if (common_area.count == 1) {
  87. /* if now, after producing, count == 1 it means
  88. * before producing count == 0
  89. * so a consumer might be waiting because
  90. * he saw that the buffer was empty
  91. * wake up that possible consumer
  92. */
  93. rc = pthread_cond_signal(&buffer_not_empty);
  94. DIE(rc != 0, "pthread_cond signal");
  95. }
  96. rc = pthread_mutex_unlock(&mutex);
  97. DIE(rc != 0, "pthread_mutex_unlock");
  98.  
  99. sleep(rand() % 3);
  100. }
  101.  
  102. return NULL;
  103. }
  104.  
  105. void *consumer_fn(void *arg)
  106. {
  107. int item_consumed, i, rc;
  108.  
  109. for (i = 0; i < NR_ITERATIONS; i++) {
  110. rc = pthread_mutex_lock(&mutex);
  111. DIE(rc != 0, "pthread_mutex_lock");
  112.  
  113. while (is_buffer_empty(&common_area)) {
  114. /* we want to consume so we must wait
  115. * until the buffer is not empty
  116. */
  117. rc = pthread_cond_wait(&buffer_not_empty, &mutex);
  118. DIE(rc != 0, "pthread_cond_wait");
  119. }
  120.  
  121. item_consumed = remove_item(&common_area);
  122.  
  123. printf("\t\tConsumed item %d\n", item_consumed);
  124.  
  125. if (common_area.count == BUFFER_SIZE - 1) {
  126. /* if now, after producing, count == BUFFER_SIZE - 1,
  127. * before producing count == BUFFER_SIZE
  128. * so a producer might be waiting since he saw that
  129. * the buffer was full wake up that
  130. * possible producer
  131. */
  132. rc = pthread_cond_signal(&buffer_not_full);
  133. DIE(rc != 0, "pthread_cond_signal");
  134. }
  135.  
  136. rc = pthread_mutex_unlock(&mutex);
  137. DIE(rc != 0, "pthread_mutex_unlock");
  138.  
  139. sleep(rand() % 3);
  140. }
  141.  
  142. return NULL;
  143. }
  144.  
  145. int main(void)
  146. {
  147. pthread_t producer_th, consumer_th;
  148. int rc;
  149.  
  150. /* initialization */
  151. init_buffer(&common_area);
  152. srand(time(NULL));
  153.  
  154. /* create the threads */
  155. rc = pthread_create(&producer_th, NULL, producer_fn, NULL);
  156. DIE(rc != 0, "pthread_create");
  157. rc = pthread_create(&consumer_th, NULL, consumer_fn, NULL);
  158. DIE(rc != 0, "pthread_create");
  159.  
  160. /* wait for the threads to finish execution */
  161. rc = pthread_join(producer_th, NULL);
  162. DIE(rc != 0, "pthread_join");
  163. rc = pthread_join(consumer_th, NULL);
  164. DIE(rc != 0, "pthread_join");
  165.  
  166. return 0;
  167. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement