title: C Producer-Consumer Using PThreads
body: <p>I am working on a problem where I am implementing a program that mimics the producer-consumer paradigm. The code that I am using works when I only have one producer and one consumer but it does not work when I add another producer and another consumer.</p>
  
  <p>I have spent a while on this and can not seem to figure out why I am getting the error <code>Synchronization Error: Producer x Just overwrote x from Slot x</code>. I have followed the problem through various tests and the problem lies in the fact that a producer is not being blocked when it notices another producer is in its critical section.</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;pthread.h&gt;
  #include &lt;semaphore.h&gt;
  #include &lt;stdlib.h&gt;
  
  void *producer (void *) ;
  void *consumer(void *) ;
  sem_t empty, full, mutex ;
  
  int buffer[10] /*note extra long space!*/ ;
  int ID[10] ;
  int in = 0 ; int out = 0 ;
  int BUFFER_SIZE = 10 ;
  int nextProduced = 0 ;
  
  main() {
      int i ;
      pthread_t TID[10] ;
  
      sem_init(&amp;empty, 0, 10) ;
      sem_init(&amp;full, 0, 0) ;
      sem_init(&amp;mutex, 0, 1) ;
  
      for(i = 0; i &lt; 10; i++) {
          ID[i] = i ;
          buffer[i] = -1 ;
      }
  
      //for(i = 0; i &lt; 5000; i += 2) {
          pthread_create(&amp;TID[0], NULL, producer, (void *) &amp;ID[0]) ;
          printf("Producer ID = %d created!\n", 0) ;
          pthread_create(&amp;TID[1], NULL, consumer, (void *) &amp;ID[1]) ;
          printf("Consumer ID = %d created!\n", 1) ;
  
          pthread_create(&amp;TID[2], NULL, producer, (void *) &amp;ID[2]) ;
          printf("Producer ID = %d created!\n", 2) ;
          pthread_create(&amp;TID[3], NULL, consumer, (void *) &amp;ID[3]) ;
          printf("Consumer ID = %d created!\n", 3) ;
      //}
  
      for(i = 0; i &lt; 10 ; i++) {
          pthread_join(TID[i], NULL) ;
      }
  }
  
  void *producer(void *Boo) {
      int *ptr;
      int ID;
      ptr = (int *) Boo;
      ID = *ptr;
      while (1) {
          nextProduced++; //Producing Integers
          /* Check to see if Overwriting unread slot */
          sem_wait(&amp;empty);
          sem_wait(&amp;mutex);
  
          if (buffer[in] != -1) {
              printf("Synchronization Error: Producer %d Just overwrote %d from Slot %d\n", ID, buffer[in], in);
              exit(0);
          }
  
          /* Looks like we are OK */
          buffer[in] = nextProduced;
          printf("Producer %d. Put %d in slot %d\n", ID, nextProduced, in);
          in = (in + 1) % BUFFER_SIZE;
          printf("incremented in!\n");
  
          sem_post(&amp;mutex);
          sem_post(&amp;full);
      }
   }
  
  void *consumer (void *Boo) {
      static int nextConsumed = 0 ;
      int *ptr ;
      int ID ;
      ptr = (int *) Boo ;
      ID = *ptr ;
      while (1) {
          sem_wait(&amp;full);
          sem_wait(&amp;mutex);
  
          nextConsumed = buffer[out];
          /*Check to make sure we did not read from an empty slot*/
          if (nextConsumed == -1) {
              printf("Synch Error: Consumer %d Just Read from empty slot %d\n", ID, out) ;
              exit(0) ;
          }
          /* We must be OK */
          printf("Consumer %d Just consumed item %d from slot %d\n", ID, nextConsumed, out) ;
          buffer[out] = -1 ;
          out = (out + 1) % BUFFER_SIZE;
  
          sem_post(&amp;mutex);
          sem_post(&amp;empty);
      }
  }
  </code></pre>
  
  <p>Ouput:</p>
  
  <pre><code>Producer ID = 0 created!
  Producer 0. Put 1 in slot 0
  Consumer ID = 1 created!
  incremented in!
  Consumer 1 Just consumed item 1 from slot 0
  Producer ID = 2 created!
  Producer 0. Put 2 in slot 1
  Synchronization Error: Producer 2 Just overwrote 2 from Slot 1
  Consumer 1 Just consumed item 2 from slot 1
  Consumer ID = 3 created!
  incremented in!
  Consumer 3 Just consumed item 2 from slot 1
  Synch Error: Consumer 1 Just Read from empty slot 2
  Producer 0. Put 4 in slot 2
  </code></pre>
  
  <p>As you can see, Producer 0 manages to put a 2 in slot 1. However, before Producer 0 can increment <code>in</code>, Producer 2 attempts to write data into Slot 1 because <code>in</code> was not incremented.</p>
  
  <p>For some reason it seems that my <code>sem_waits()</code> are not working. Can anybody help me out?</p>