Advertisement
Guest User

PrintServerOrginal

a guest
Mar 31st, 2023
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.28 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #include <semaphore.h>
  5.  
  6. #define SIZE 5
  7. #define NUMB_THREADS 6
  8. #define PRODUCER_LOOPS 2
  9.  
  10. typedef int buffer_t;
  11. buffer_t buffer[SIZE];
  12. int buffer_index;
  13.  
  14. pthread_mutex_t buffer_mutex;
  15. /* initially buffer will be empty. full_sem
  16. will be initialized to buffer SIZE, which means
  17. SIZE number of producer threads can write to it.
  18. And empty_sem will be initialized to 0, so no
  19. consumer can read from buffer until a producer
  20. thread posts to empty_sem */
  21. sem_t full_sem; /* when 0, buffer is full */
  22. sem_t empty_sem; /* when 0, buffer is empty. Kind of
  23. like an index for the buffer */
  24.  
  25.  
  26.  
  27. void insertbuffer(buffer_t value) {
  28. if (buffer_index < SIZE) {
  29. buffer[buffer_index++] = value;
  30. } else {
  31. printf("Buffer overflow\n");
  32. }
  33. }
  34.  
  35. buffer_t dequeuebuffer() {
  36. if (buffer_index > 0) {
  37. return buffer[--buffer_index]; // buffer_index-- would be error!
  38. } else {
  39. printf("Buffer underflow\n");
  40. }
  41. return 0;
  42. }
  43.  
  44.  
  45. void *producer(void *thread_n) {
  46. int thread_numb = *(int *)thread_n;
  47. buffer_t value;
  48. int i=0;
  49. while (i++ < PRODUCER_LOOPS) {
  50. sleep(rand() % 10);
  51. value = rand() % 100;
  52. sem_wait(&full_sem); // sem=0: wait. sem>0: go and decrement it
  53. /* possible race condition here. After this thread wakes up,
  54. another thread could aqcuire mutex before this one, and add to list.
  55. Then the list would be full again
  56. and when this thread tried to insert to buffer there would be
  57. a buffer overflow error */
  58. pthread_mutex_lock(&buffer_mutex); /* protecting critical section */
  59. insertbuffer(value);
  60. pthread_mutex_unlock(&buffer_mutex);
  61. sem_post(&empty_sem); // post (increment) emptybuffer semaphore
  62. printf("Producer %d added %d to buffer\n", thread_numb, value);
  63. }
  64. pthread_exit(0);
  65. }
  66.  
  67. void *consumer(void *thread_n) {
  68. int thread_numb = *(int *)thread_n;
  69. buffer_t value;
  70. int i=0;
  71. while (i++ < PRODUCER_LOOPS) {
  72. sem_wait(&empty_sem);
  73. /* there could be race condition here, that could cause
  74. buffer underflow error */
  75. pthread_mutex_lock(&buffer_mutex);
  76. value = dequeuebuffer(value);
  77. pthread_mutex_unlock(&buffer_mutex);
  78. sem_post(&full_sem); // post (increment) fullbuffer semaphore
  79. printf("Consumer %d dequeue %d from buffer\n", thread_numb, value);
  80. }
  81. pthread_exit(0);
  82. }
  83.  
  84. int main(int argc, int **argv) {
  85. buffer_index = 0;
  86.  
  87. pthread_mutex_init(&buffer_mutex, NULL);
  88. sem_init(&full_sem, // sem_t *sem
  89. 0, // int pshared. 0 = shared between threads of process, 1 = shared between processes
  90. SIZE); // unsigned int value. Initial value
  91. sem_init(&empty_sem,
  92. 0,
  93. 0);
  94. /* full_sem is initialized to buffer size because SIZE number of
  95. producers can add one element to buffer each. They will wait
  96. semaphore each time, which will decrement semaphore value.
  97. empty_sem is initialized to 0, because buffer starts empty and
  98. consumer cannot take any element from it. They will have to wait
  99. until producer posts to that semaphore (increments semaphore
  100. value) */
  101. pthread_t thread[NUMB_THREADS];
  102. int thread_numb[NUMB_THREADS];
  103. int i;
  104. for (i = 0; i < NUMB_THREADS; ) {
  105. thread_numb[i] = i;
  106. pthread_create(thread + i, // pthread_t *t
  107. NULL, // const pthread_attr_t *attr
  108. producer, // void *(*start_routine) (void *)
  109. thread_numb + i); // void *arg
  110. i++;
  111. thread_numb[i] = i;
  112. // playing a bit with thread and thread_numb pointers...
  113. pthread_create(&thread[i], // pthread_t *t
  114. NULL, // const pthread_attr_t *attr
  115. consumer, // void *(*start_routine) (void *)
  116. &thread_numb[i]); // void *arg
  117. i++;
  118. }
  119.  
  120. for (i = 0; i < NUMB_THREADS; i++)
  121. pthread_join(thread[i], NULL);
  122.  
  123. pthread_mutex_destroy(&buffer_mutex);
  124. sem_destroy(&full_sem);
  125. sem_destroy(&empty_sem);
  126.  
  127. return 0;
  128. }
Tags: code c
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement