fork download
  1. #include <pthread.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include </usr/include/semaphore.h>
  5.  
  6. // for sleep
  7. #include <unistd.h>
  8.  
  9. #define BUFF_SIZE 5 /* total number of slots */
  10. #define NP 3 /* total number of producers */
  11. #define NC 3 /* total number of consumers */
  12. #define NITERS 4 /* number of items produced/consumed */
  13.  
  14. typedef struct
  15. {
  16. int buf[BUFF_SIZE]; /* shared var */
  17. int in; /* buf[in%BUFF_SIZE] is the first empty slot */
  18. int out; /* buf[out%BUFF_SIZE] is the first full slot */
  19. sem_t full; /* keep track of the number of full spots */
  20. sem_t empty; /* keep track of the number of empty spots */
  21.  
  22. // use correct type here
  23. pthread_mutex_t mutex; /* enforce mutual exclusion to shared data */
  24. } sbuf_t;
  25.  
  26. sbuf_t shared;
  27.  
  28.  
  29. void *Producer(void *arg)
  30. {
  31. int i, item, index;
  32.  
  33. index = (int)arg;
  34.  
  35.  
  36. for (i=0; i < NITERS; i++)
  37. {
  38.  
  39. /* Produce item */
  40. item = i;
  41.  
  42. /* Prepare to write item to buf */
  43.  
  44. /* If there are no empty slots, wait */
  45. sem_wait(&shared.empty);
  46. /* If another thread uses the buffer, wait */
  47. pthread_mutex_lock(&shared.mutex);
  48. shared.buf[shared.in] = item;
  49. shared.in = (shared.in+1)%BUFF_SIZE;
  50. printf("[P%d] Producing %d ...\n", index, item);
  51. fflush(stdout);
  52. /* Release the buffer */
  53. pthread_mutex_unlock(&shared.mutex);
  54. /* Increment the number of full slots */
  55. sem_post(&shared.full);
  56.  
  57. /* Interleave producer and consumer execution */
  58. if (i % 2 == 1) sleep(1);
  59. }
  60. return NULL;
  61. }
  62.  
  63. void *Consumer(void *arg)
  64. {
  65. int i, item, index;
  66.  
  67. index = (int)arg;
  68. for (i=NITERS; i > 0; i--) {
  69. sem_wait(&shared.full);
  70. pthread_mutex_lock(&shared.mutex);
  71. item=i;
  72. item=shared.buf[shared.out];
  73. shared.out = (shared.out+1)%BUFF_SIZE;
  74. printf("[C%d] Consuming %d ...\n", index, item);
  75. fflush(stdout);
  76. /* Release the buffer */
  77. pthread_mutex_unlock(&shared.mutex);
  78. /* Increment the number of full slots */
  79. sem_post(&shared.empty);
  80.  
  81. /* Interleave producer and consumer execution */
  82. if (i % 2 == 1) sleep(1);
  83. }
  84. return NULL;
  85. }
  86.  
  87. int main()
  88. {
  89. pthread_t idP, idC;
  90. int index;
  91.  
  92. sem_init(&shared.full, 0, 0);
  93. sem_init(&shared.empty, 0, BUFF_SIZE);
  94. pthread_mutex_init(&shared.mutex, NULL);
  95. for (index = 0; index < NP; index++)
  96. {
  97. /* Create a new producer */
  98. pthread_create(&idP, NULL, Producer, (void*)index);
  99. }
  100. /*create a new Consumer*/
  101. for(index=0; index<NC; index++)
  102. {
  103. pthread_create(&idC, NULL, Consumer, (void*)index);
  104. }
  105.  
  106.  
  107.  
  108. pthread_exit(NULL);
  109. }
  110.  
Success #stdin #stdout 0s 5312KB
stdin
Standard input is empty
stdout
[P2] Producing 0 ...
[P2] Producing 1 ...
[C2] Consuming  0 ...
[C1] Consuming  1 ...
[P1] Producing 0 ...
[P1] Producing 1 ...
[C0] Consuming  0 ...
[C2] Consuming  1 ...
[P0] Producing 0 ...
[P0] Producing 1 ...
[C1] Consuming  0 ...
[C0] Consuming  1 ...
[P2] Producing 2 ...
[P2] Producing 3 ...
[C0] Consuming  2 ...
[C1] Consuming  3 ...
[P1] Producing 2 ...
[P1] Producing 3 ...
[P0] Producing 2 ...
[P0] Producing 3 ...
[C0] Consuming  2 ...
[C2] Consuming  3 ...
[C2] Consuming  2 ...
[C1] Consuming  3 ...