fork(5) download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #include <unistd.h>
  5. #include <time.h>
  6.  
  7. #define BUFFER_SIZE 99
  8. #define PRODUCTION_COST 0
  9.  
  10. char producer_array[BUFFER_SIZE * 10];
  11. char consumer_array[BUFFER_SIZE];
  12. int producer_index = 0;
  13. int consumer_index = 0;
  14.  
  15. pthread_mutex_t producer_mutex;
  16. pthread_mutex_t consumer_mutex;
  17.  
  18. void* producer1(void* arg);
  19. void* producer2(void* arg);
  20. void* producer3(void* arg);
  21. void* consumer(void* arg);
  22.  
  23. int main()
  24. {
  25. srand(time(NULL)); // Seed the random number generator
  26.  
  27. pthread_mutex_init(&producer_mutex, NULL);
  28. pthread_mutex_init(&consumer_mutex, NULL);
  29.  
  30. pthread_t producer_threads[3];
  31. pthread_t consumer_threads[3];
  32.  
  33. pthread_create(&producer_threads[0], NULL, producer1, NULL);
  34. pthread_create(&producer_threads[1], NULL, producer2, NULL);
  35. pthread_create(&producer_threads[2], NULL, producer3, NULL);
  36. pthread_create(&consumer_threads[0], NULL, consumer, NULL);
  37. pthread_create(&consumer_threads[1], NULL, consumer, NULL);
  38. pthread_create(&consumer_threads[2], NULL, consumer, NULL);
  39.  
  40. for (int i = 0; i < 3; i++) {
  41. pthread_join(producer_threads[i], NULL);
  42. pthread_join(consumer_threads[i], NULL);
  43. }
  44.  
  45. printf("Consumer Array: ");
  46. for (int i = 0; i < consumer_index; i++)
  47. {
  48. printf("%c", consumer_array[i]);
  49. }
  50. printf("\n\n");
  51.  
  52. printf("Producer Array: ");
  53. for (int i = 0; i < producer_index; i++)
  54. {
  55. printf("%c", producer_array[i]);
  56. }
  57. printf("\n");
  58.  
  59. pthread_mutex_destroy(&producer_mutex);
  60. pthread_mutex_destroy(&consumer_mutex);
  61.  
  62. return 0;
  63. }
  64.  
  65. void* producer1(void* arg)
  66. {
  67. while (consumer_index < BUFFER_SIZE)
  68. {
  69. char product;
  70. int rand_int = rand() % 2;
  71.  
  72. if (rand_int == 0)
  73. {
  74. product = 'B';
  75. usleep(PRODUCTION_COST);
  76. }
  77. else
  78. {
  79. product = 'G';
  80. usleep(PRODUCTION_COST);
  81. }
  82.  
  83. pthread_mutex_lock(&producer_mutex);
  84. char last_char = (producer_index > 0) ? producer_array[producer_index - 1] : '\0';
  85. if (product == 'B')
  86. {
  87. if (last_char == 'R' || last_char == '\0')
  88. {
  89. producer_array[producer_index++] = 'B';
  90. }
  91. }
  92. else if (product == 'G')
  93. {
  94. if (last_char == 'B')
  95. {
  96. producer_array[producer_index++] = 'G';
  97. }
  98. }
  99. pthread_mutex_unlock(&producer_mutex);
  100. }
  101. return NULL;
  102. }
  103.  
  104. void* producer2(void* arg)
  105. {
  106. while (consumer_index < BUFFER_SIZE)
  107. {
  108. char product;
  109. int rand_int = rand() % 2;
  110.  
  111. if (rand_int == 0)
  112. {
  113. product = 'G';
  114. usleep(PRODUCTION_COST);
  115. }
  116. else
  117. {
  118. product = 'R';
  119. usleep(PRODUCTION_COST);
  120. }
  121.  
  122. pthread_mutex_lock(&producer_mutex);
  123. char last_char = (producer_index > 0) ? producer_array[producer_index - 1] : '\0';
  124. if (product == 'G')
  125. {
  126. if (last_char == 'B')
  127. {
  128. producer_array[producer_index++] = 'G';
  129. }
  130. }
  131. else if (product == 'R')
  132. {
  133. if (last_char == 'G')
  134. {
  135. producer_array[producer_index++] = 'R';
  136. }
  137. }
  138. pthread_mutex_unlock(&producer_mutex);
  139. }
  140. return NULL;
  141. }
  142.  
  143. void* producer3(void* arg)
  144. {
  145. while (consumer_index < BUFFER_SIZE)
  146. {
  147. char product;
  148. int rand_int = rand() % 2;
  149.  
  150. if (rand_int == 0)
  151. {
  152. product = 'R';
  153. usleep(PRODUCTION_COST);
  154. }
  155. else
  156. {
  157. product = 'B';
  158. usleep(PRODUCTION_COST);
  159. }
  160.  
  161. pthread_mutex_lock(&producer_mutex);
  162. char last_char = (producer_index > 0) ? producer_array[producer_index - 1] : '\0';
  163. if (product == 'R')
  164. {
  165. if (last_char == 'G')
  166. {
  167. producer_array[producer_index++] = 'R';
  168. }
  169. }
  170. else if (product == 'B')
  171. {
  172. if (last_char == 'R' || last_char == '\0')
  173. {
  174. producer_array[producer_index++] = 'B';
  175. }
  176. }
  177. pthread_mutex_unlock(&producer_mutex);
  178. }
  179. return NULL;
  180. }
  181.  
  182. void* consumer(void* arg)
  183. {
  184. while (consumer_index < BUFFER_SIZE)
  185. {
  186. pthread_mutex_lock(&consumer_mutex);
  187. while (consumer_index < BUFFER_SIZE)
  188. {
  189. char last_c_char = (consumer_index > 0) ? consumer_array[consumer_index - 1] : '\0';
  190. pthread_mutex_lock(&producer_mutex);
  191. char last_p_char = (producer_index > 0) ? producer_array[producer_index - 1] : '\0';
  192.  
  193. if ((last_c_char == 'B' && last_p_char == 'G') ||
  194. (last_c_char == 'G' && last_p_char == 'R') ||
  195. (last_c_char == 'R' && last_p_char == 'B') ||
  196. (last_c_char == '\0' && last_p_char == 'B'))
  197. {
  198. consumer_array[consumer_index++] = producer_array[--producer_index];
  199. }
  200. pthread_mutex_unlock(&producer_mutex);
  201.  
  202. if (consumer_index >= BUFFER_SIZE) {
  203. break;
  204. }
  205. }
  206. pthread_mutex_unlock(&consumer_mutex);
  207. usleep(1); // Allow other threads to acquire the mutex
  208. }
  209. return NULL;
  210. }
  211.  
Success #stdin #stdout 0.57s 5268KB
stdin
Standard input is empty
stdout
Consumer Array: BGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGR

Producer Array: BGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBG