fork download
  1. #include <pthread.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5.  
  6. // use 4 cons 4 prod
  7. // instead of random number, use 1000 for all prod
  8. // real time lib is optional
  9. // Due thurs 11pm
  10.  
  11.  
  12. #define BSIZE 10
  13. #define NUM_ITEMS 20
  14. #define NUM_THREADS 8
  15. #define NUM_PRODUCERS 4
  16. #define NUM_CONSUMERS 4
  17.  
  18. typedef enum { false, true } bool;
  19.  
  20. int buf[BSIZE];
  21. int nextin=0, nextout=0;
  22.  
  23. pthread_mutex_t lock; // a shared lock veriale
  24. pthread_cond_t empty, full;
  25. bool isFull = false, isEmpty = false;
  26. int bufCounter = 0;
  27.  
  28. void * producer(void *); // function for producer thread
  29. void * consumer(void *); // function for consumer thread
  30.  
  31. pthread_t tid[NUM_THREADS]; // array of thread IDs
  32.  
  33.  
  34. int main( int argc, char *argv[] )
  35. {
  36. int i;
  37.  
  38. pthread_cond_init(&full, NULL);
  39. pthread_cond_init(&empty, NULL);
  40.  
  41. printf("\n **** Main Program creating threads **** \n");
  42.  
  43. for (i = 0; i < NUM_PRODUCERS; i++)
  44. pthread_create(&tid[i], NULL, producer, NULL); // Creating producers
  45. for (i = NUM_PRODUCERS; i < NUM_THREADS; i++)
  46. pthread_create(&tid[i], NULL, consumer, NULL); // Creating consumers
  47.  
  48. for ( i = 0; i < NUM_THREADS; i++)
  49. pthread_join(tid[i], NULL);
  50.  
  51. printf("\n *** main() reporting: all %d threads have terminated ***\n\n ", i);
  52.  
  53. return 0;
  54.  
  55. } /* main */
  56.  
  57.  
  58.  
  59. void * producer(void * parm)
  60. {
  61. int i, num;
  62.  
  63. printf("\n ++++ Producer started ++++ \n");
  64.  
  65. for(i=0; i < NUM_ITEMS; i++)
  66. { // produce items
  67.  
  68. num = rand() % 1000;
  69.  
  70. pthread_mutex_lock(&lock); // lock the buffer when adding num
  71.  
  72. if (isFull == true)
  73. pthread_cond_wait(&empty, &lock);
  74.  
  75. buf[nextin++] = num;
  76.  
  77. nextin %= BSIZE; // make the buffer circular
  78. bufCounter++; // Increment bufCounter
  79.  
  80. isEmpty = false;
  81. if (bufCounter == BSIZE){
  82. isFull = true;
  83. pthread_cond_signal(&full);
  84. }
  85. pthread_mutex_unlock(&lock); // get out the critical section
  86.  
  87. }
  88.  
  89.  
  90. printf("\n ++++ Producer exiting ++++\n");
  91. pthread_exit(0);
  92. }
  93.  
  94. void * consumer(void * parm)
  95. {
  96. int i, num;
  97.  
  98. printf("\n ==== Consumer started ==== \n");
  99.  
  100. for(i=0; i < NUM_ITEMS; i++)
  101. {
  102. // get item from the buffer and consume it
  103.  
  104. pthread_mutex_lock(&lock); // lock the buffer when removing item
  105.  
  106. if (isEmpty == true)
  107. pthread_cond_wait(&full, &lock);
  108.  
  109. num = buf[nextout++];
  110. nextout %= BSIZE; // make the buffer circular
  111. bufCounter--;
  112.  
  113. printf(" Consuming item #[%d]: %d\n", i, num);
  114.  
  115. isFull = false;
  116. pthread_cond_signal(&full);
  117. if (bufCounter == 0){
  118. isEmpty = true;
  119. }
  120. pthread_mutex_unlock(&lock); // unlock the buffer and get out CS
  121.  
  122. }
  123.  
  124.  
  125. printf("\n ==== Consumer exiting ====\n");
  126. pthread_exit(0);
  127. }
  128.  
Success #stdin #stdout 0s 93504KB
stdin
Standard input is empty
stdout
 **** Main Program creating threads **** 

 ==== Consumer started ==== 
 Consuming item #[0]: 0
 Consuming item #[1]: 0
 Consuming item #[2]: 0
 Consuming item #[3]: 0
 Consuming item #[4]: 0
 Consuming item #[5]: 0
 Consuming item #[6]: 0
 Consuming item #[7]: 0
 Consuming item #[8]: 0
 Consuming item #[9]: 0
 Consuming item #[10]: 0
 Consuming item #[11]: 0
 Consuming item #[12]: 0
 Consuming item #[13]: 0
 Consuming item #[14]: 0
 Consuming item #[15]: 0
 Consuming item #[16]: 0
 Consuming item #[17]: 0
 Consuming item #[18]: 0
 Consuming item #[19]: 0

 ==== Consumer exiting ====

 ==== Consumer started ==== 
 Consuming item #[0]: 0
 Consuming item #[1]: 0
 Consuming item #[2]: 0
 Consuming item #[3]: 0
 Consuming item #[4]: 0
 Consuming item #[5]: 0
 Consuming item #[6]: 0
 Consuming item #[7]: 0
 Consuming item #[8]: 0
 Consuming item #[9]: 0
 Consuming item #[10]: 0
 Consuming item #[11]: 0
 Consuming item #[12]: 0
 Consuming item #[13]: 0
 Consuming item #[14]: 0
 Consuming item #[15]: 0
 Consuming item #[16]: 0
 Consuming item #[17]: 0
 Consuming item #[18]: 0
 Consuming item #[19]: 0

 ==== Consumer exiting ====

 ==== Consumer started ==== 
 Consuming item #[0]: 0
 Consuming item #[1]: 0
 Consuming item #[2]: 0
 Consuming item #[3]: 0
 Consuming item #[4]: 0
 Consuming item #[5]: 0
 Consuming item #[6]: 0
 Consuming item #[7]: 0
 Consuming item #[8]: 0
 Consuming item #[9]: 0
 Consuming item #[10]: 0
 Consuming item #[11]: 0
 Consuming item #[12]: 0
 Consuming item #[13]: 0
 Consuming item #[14]: 0
 Consuming item #[15]: 0
 Consuming item #[16]: 0
 Consuming item #[17]: 0
 Consuming item #[18]: 0
 Consuming item #[19]: 0

 ==== Consumer exiting ====

 ==== Consumer started ==== 
 Consuming item #[0]: 0
 Consuming item #[1]: 0
 Consuming item #[2]: 0
 Consuming item #[3]: 0
 Consuming item #[4]: 0
 Consuming item #[5]: 0
 Consuming item #[6]: 0
 Consuming item #[7]: 0
 Consuming item #[8]: 0
 Consuming item #[9]: 0
 Consuming item #[10]: 0
 Consuming item #[11]: 0
 Consuming item #[12]: 0
 Consuming item #[13]: 0
 Consuming item #[14]: 0
 Consuming item #[15]: 0
 Consuming item #[16]: 0
 Consuming item #[17]: 0
 Consuming item #[18]: 0
 Consuming item #[19]: 0

 ==== Consumer exiting ====

 ++++ Producer started ++++ 

 ++++ Producer exiting ++++

 ++++ Producer started ++++ 

 ++++ Producer exiting ++++

 ++++ Producer started ++++ 

 ++++ Producer exiting ++++

 ++++ Producer started ++++ 

 ++++ Producer exiting ++++

 *** main() reporting: all 8 threads have terminated ***