title: Producer consumer pthreads program not finishing
body: <p>So I have to make a program that uses 4 producer threads and 4 consumer threads, with an array that holds 10 random numbers at a time. Once that array is full, the producer must wait until those 10 numbers are consumed by the consumer, and then the consumer waits for the array to be full again. I have to do this with 1000 random numbers.</p>
  
  <p>The problem is that the program never actually finishes, and I don't know why. I'm testing it out with 20 numbers, but the output is very scrambled and out of order, which isn't making this easier. I'll put the code and output below.</p>
  
  <pre><code>#include &lt;pthread.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;iostream&gt;
  #include &lt;time.h&gt;
  
  // use 4 cons 4 prod
  // instead of random number, use 1000 for all prod
  // real time lib is optional
  // Due thurs 11pm
  
  using namespace std;
  
  #define BSIZE 10
  #define NUM_ITEMS 20
  #define NUM_THREADS 8
  #define NUM_PRODUCERS 4
  #define NUM_CONSUMERS 4
  
  
  int buf[BSIZE];
  int nextin=0, nextout=0;
  
  pthread_mutex_t lock;       // a shared lock veriale
  pthread_cond_t empty, full;
  bool isFull = false, isEmpty = false;
  int bufCounter = 0;
  
  void * producer(void *);    // function for producer thread
  void * consumer(void *);    // function for consumer thread
  
  pthread_t tid[NUM_THREADS];      // array of thread IDs
  
  
  int main( int argc, char *argv[] ) 
  {
      int i;
  
      pthread_cond_init(&amp;full, NULL);
      pthread_cond_init(&amp;empty, NULL);
  
      printf("\n **** Main Program creating threads **** \n");
  
      for (i = 0; i &lt; NUM_PRODUCERS; i++)
          pthread_create(&amp;tid[i], NULL, producer, NULL); // Creating producers 
      for (i = NUM_PRODUCERS; i &lt; NUM_THREADS; i++)
          pthread_create(&amp;tid[i], NULL, consumer, NULL); // Creating consumers
  
      for ( i = 0; i &lt; NUM_THREADS; i++)
          pthread_join(tid[i], NULL);
  
      printf("\n *** main() reporting: all %d threads have terminated ***\n\n ", i);
  
      return 0; 
  
  }  /* main */
  
  
  
  void * producer(void * parm)
  {
      int i, num;
  
      printf("\n ++++ Producer started ++++ \n");
  
      for(i=0; i &lt; NUM_ITEMS; i++)
      { // produce items  
  
          num = rand() % 1000;
  
          pthread_mutex_lock(&amp;lock);      // lock the buffer when adding num
  
          if (isFull == true)
              pthread_cond_wait(&amp;empty, &amp;lock);
  
          buf[nextin++] = num;
  
          nextin %= BSIZE;    // make the buffer circular
          bufCounter++; // Increment bufCounter
  
          if (bufCounter == BSIZE){
              isFull = true;
              isEmpty = false;
          }
          pthread_cond_signal(&amp;full);
          pthread_mutex_unlock(&amp;lock);    // get out the critical section 
  
      }
  
  
      printf("\n ++++ Producer exiting ++++\n");
      pthread_exit(0);
  }    
  
  void * consumer(void * parm)
  {
      int i, num;
  
      printf("\n ==== Consumer started ==== \n");
  
      for(i=0; i &lt; NUM_ITEMS; i++)
      {       
          // get item from the buffer and consume it
  
          pthread_mutex_lock(&amp;lock);      // lock the buffer when removing item
  
          if (isEmpty == true)
              pthread_cond_wait(&amp;full, &amp;lock);
  
          num = buf[nextout++];
          nextout %= BSIZE;       // make the buffer circular
          bufCounter--;       
  
          printf(" Consuming item #[%d]: %d\n", i, num);
  
          if (bufCounter == 0){
              isEmpty = true;
              isFull = false;
          }   
          pthread_cond_signal(&amp;empty);
          pthread_mutex_unlock(&amp;lock);      // unlock the buffer and get out CS
  
      }
  
  
      printf("\n ==== Consumer exiting ====\n");
      pthread_exit(0);
  }
  </code></pre>
  
  <p>I really appreciate any help, and I know there's a lot of code here. Sorry.</p>
  
  <p>EDIT: Here's the full output.</p>
  
  <pre><code> **** Main Program creating threads ****
  
   ++++ Producer started ++++
  
   ++++ Producer started ++++
  
   ++++ Producer started ++++
  
   ++++ Producer started ++++
  
   ==== Consumer started ====
   Consuming item #[0]: 838
   Consuming item #[1]: 758
   Consuming item #[2]: 113
   Consuming item #[3]: 515
  
   ==== Consumer started ====
   Consuming item #[4]: 51
   Consuming item #[5]: 627
  
   ==== Consumer started ====
  
   ==== Consumer started ====
   Consuming item #[6]: 10
   Consuming item #[7]: 419
   Consuming item #[8]: 212
   Consuming item #[9]: 86
   Consuming item #[10]: 749
   Consuming item #[0]: 225
   Consuming item #[11]: 543
   Consuming item #[1]: 89
   Consuming item #[2]: 84
   Consuming item #[3]: 137
   Consuming item #[0]: 566
   Consuming item #[0]: 183
   Consuming item #[1]: 978
   Consuming item #[2]: 767
   Consuming item #[3]: 495
   Consuming item #[4]: 311
   Consuming item #[5]: 367
   Consuming item #[6]: 54
   Consuming item #[7]: 966
   Consuming item #[12]: 882
   Consuming item #[1]: 736
   Consuming item #[2]: 524
   Consuming item #[3]: 505
   Consuming item #[4]: 60
   Consuming item #[5]: 394
   Consuming item #[6]: 102
   Consuming item #[7]: 851
   Consuming item #[8]: 67
   Consuming item #[9]: 653
   Consuming item #[10]: 561
   Consuming item #[11]: 96
  
   ++++ Producer exiting ++++
   Consuming item #[8]: 31
   Consuming item #[9]: 754
   Consuming item #[10]: 188
   Consuming item #[11]: 85
   Consuming item #[12]: 143
   Consuming item #[13]: 967
   Consuming item #[14]: 145
   Consuming item #[15]: 406
   Consuming item #[16]: 165
   Consuming item #[17]: 403
   Consuming item #[4]: 562
   Consuming item #[5]: 628
   Consuming item #[13]: 920
   Consuming item #[14]: 834
   Consuming item #[15]: 803
   Consuming item #[16]: 444
   Consuming item #[6]: 962
   Consuming item #[7]: 318
  
   ++++ Producer exiting ++++
   Consuming item #[8]: 422
   Consuming item #[9]: 327
   Consuming item #[10]: 457
   Consuming item #[11]: 945
   Consuming item #[12]: 479
   Consuming item #[13]: 983
   Consuming item #[14]: 751
   Consuming item #[18]: 894
  
   ++++ Producer exiting ++++
   Consuming item #[19]: 670
  
   ==== Consumer exiting ====
   Consuming item #[15]: 259
   Consuming item #[16]: 248
   Consuming item #[17]: 353
   Consuming item #[18]: 757
   Consuming item #[17]: 629
   Consuming item #[18]: 306
   Consuming item #[19]: 606
  
   ==== Consumer exiting ====
   Consuming item #[12]: 990
   Consuming item #[13]: 738
   Consuming item #[14]: 516
   Consuming item #[15]: 414
   Consuming item #[16]: 262
  
   ++++ Producer exiting ++++
   Consuming item #[17]: 116
  </code></pre>
  
  <p>You can see that the program just stops and sits there, so I'm not sure if it's just done with all the numbers, but it gets called to wait again.</p>