fork download
  1. #include <stdio.h>
  2. #include <semaphore.h>
  3. #include <pthread.h>
  4. #include <stdlib.h>
  5.  
  6. sem_t mutex;
  7. sem_t empty;
  8. sem_t full;
  9. sem_t limit;
  10.  
  11. int p_shared_value = 0;
  12.  
  13. int *buffer;
  14. int in = 0;
  15. int out = 0;
  16.  
  17. typedef struct _data_t {
  18.  
  19. int tid;
  20. int buffer_size;
  21. int upper_limit;
  22.  
  23. } data_t;
  24.  
  25. void *produce(void *arg) {
  26.  
  27. data_t *passedData = (data_t *) arg;
  28.  
  29. while (1) {
  30.  
  31.  
  32. sem_wait(&limit);
  33.  
  34. if (passedData->upper_limit == p_shared_value) {
  35. printf("Producer[#%d] terminated\n", passedData->tid);
  36. sem_post(&limit);
  37. pthread_exit(NULL);
  38. } else {
  39.  
  40. sem_wait(&empty);
  41. sem_wait(&mutex);
  42.  
  43. buffer[in] = p_shared_value;
  44. printf("[PRODUCED] at index : %d, by TID : %d VALUE : %d\n", in, passedData->tid, p_shared_value);
  45. p_shared_value++;
  46. in = (in + 1) % passedData->buffer_size;
  47.  
  48. sem_post(&mutex);
  49. sem_post(&limit);
  50. sem_post(&full);
  51. }
  52. }
  53. }
  54.  
  55. void *consume(void *arg) {
  56.  
  57. data_t *passedData = (data_t *) arg;
  58.  
  59. while (1) {
  60.  
  61.  
  62. if (passedData->upper_limit == p_shared_value) {
  63. printf("Consumer[#%d] terminated\n", passedData->tid);
  64. pthread_exit(NULL);
  65. } else {
  66. sem_wait(&full);
  67. sem_wait(&mutex);
  68.  
  69. printf("[CONSUMED] at index : %d, by TID : %d VALUE : %d\n", out, passedData->tid, buffer[out]);
  70. out = (out + 1) % passedData->buffer_size;
  71.  
  72. sem_post(&mutex);
  73. sem_post(&empty);
  74. }
  75. }
  76. }
  77.  
  78.  
  79. int main(int argc, char *argv[]) {
  80.  
  81. unsigned int buffer_size = (unsigned int) atoi(argv[1]);
  82. int num_producers = atoi(argv[2]);
  83. int num_consumers = atoi(argv[3]);
  84. int upper_limit = atoi(argv[4]);
  85.  
  86. buffer = malloc(buffer_size * sizeof(int));
  87.  
  88. sem_init(&empty, 0, buffer_size);
  89. sem_init(&full, 0, 0);
  90. sem_init(&mutex, 0, 1);
  91. sem_init(&limit, 0, 1);
  92.  
  93. pthread_t c_threads[num_consumers];
  94. pthread_t p_threads[num_producers];
  95.  
  96.  
  97. puts("Passed arguments");
  98. printf("%d - %d - %d - %d\n", buffer_size, num_producers, num_consumers, upper_limit);
  99. puts("************************");
  100.  
  101. data_t p_structs[num_producers];
  102. data_t c_structs[num_consumers];
  103.  
  104.  
  105. for (int i = 0; i < num_producers; i++) {
  106. p_structs[i].buffer_size = buffer_size;
  107. p_structs[i].tid = i;
  108. p_structs[i].upper_limit = upper_limit;
  109.  
  110. pthread_create(&(p_threads[i]), NULL, &produce, ((void *) (&p_structs[i])));
  111. }
  112.  
  113. for (int i = 0; i < num_consumers; i++) {
  114. c_structs[i].buffer_size = buffer_size;
  115. c_structs[i].tid = i;
  116. c_structs[i].upper_limit = upper_limit;
  117.  
  118. pthread_create(&c_threads[i], NULL, &consume, ((void *) (&c_structs[i])));
  119. }
  120.  
  121.  
  122. for (int i = 0; i < num_producers; i++) {
  123. pthread_join(p_threads[i], NULL);
  124. }
  125.  
  126. for (int i = 0; i < num_consumers; i++) {
  127. pthread_join(c_threads[i], NULL);
  128. }
  129.  
  130.  
  131. return 0;
  132. }
Runtime error #stdin #stdout 0s 9296KB
stdin
5 3 4 10
stdout
Standard output is empty