title: Producer-consumer using semaphore in C
body: <p>There is producer-consumer problem is written using semaphore. In below code, there is an issue of synchronization execution while the consumer is created. And for its solution, sleep statement is added in switch block of the consumer.<br> Kindly help me with the efficient solution for the synchronization. Any suggestion for the improvement of code is really helpful.</p>
  
  <pre><code>#include&lt;stdio.h&gt;
  #include&lt;pthread.h&gt;
  #include&lt;unistd.h&gt;
  #include&lt;semaphore.h&gt; /* sem_t */
  #include&lt;stdlib.h&gt;
  
  #define BUF_SIZE 2
  
  struct buffer {
          int data;
  };
  
  struct buffer buf[BUF_SIZE];
  
  sem_t fill, empty;
  
  int value, i;
  
  void *producer(void *data);
  void *consumer(void *data);
  
  int main(void)
  {
      int sel, prod_data, cons_data;
      int k;
  
      if (sem_init(&amp;empty, 0, BUF_SIZE)) {
          printf("Error: semaphore not initialize\n");
          return -1;
      }
      if (sem_init(&amp;fill, 0, 0)) {
          printf("Error: semaphore not initialize\n");
          return -1;
      }
  
      while (1) {
          printf(".........................................................\n");
          printf("Selection\n");
          printf("Producer : 1 | Consumer : 2 | Display : 3 | Exit : 0 || ");
          scanf("%d",&amp;sel);
          printf(".........................................................\n");
  
          switch (sel) {
          case 1:
              sem_getvalue(&amp;empty, &amp;value);
  //          printf("Prod_e: %d\n", value);
              sem_getvalue(&amp;fill, &amp;value);
  //          printf("Prod_f: %d\n", value);
              printf("\nProducer\n");
              pthread_t prod_t;
              printf("Enter data:");
              scanf("%d", &amp;prod_data);
              if (pthread_create(&amp;prod_t, NULL, producer, (void *) &amp;prod_data)) {
                  printf("Error: thread not created\n");
                  return -1;
              }
              break;
          case 2:
              printf("\nConsumer\n");
              sem_getvalue(&amp;empty, &amp;value);
  //          printf("Cons_e: %d\n", value);
              sem_getvalue(&amp;fill, &amp;value);
  //          printf("Cons_f: %d\n", value);
              pthread_t con_t;
              if (pthread_create(&amp;con_t, NULL, consumer, (void *) &amp;cons_data)) {
                  printf("Error: thread not created\n");
                  return -1;
              }
              if (i == 0) {
                  printf("Buffer empty\n");
                  break;
              }
  //              sleep(1); // if commented then synchronization issue
              printf("Consume data: %d\n", cons_data);
              break;
          case 3:
                  if (i == 0) {
                      printf("Buffer empty\n");
                      break;
                  }
                  for (k = 0; k &lt; i; k++)
                      printf("buf[%d]: %d\n", k, buf[k].data);
                  break;
          case 0:
              sem_destroy(&amp;fill);
              sem_destroy(&amp;empty);
              exit (0);
              break;
          }
      }
      sem_destroy(&amp;fill);
      sem_destroy(&amp;empty);
      return 0;
  }
  
  void *producer(void *arg)
  {
      int data = *(int *) arg;
  
      if (sem_wait(&amp;empty)) { /* wait */
          printf("Error: sem wait fail\n");
          pthread_exit(NULL);
      }
  
      buf[i].data = data;
      i++;
  
      if (sem_post(&amp;fill)) { /* post */
          printf("Error: sem wait fail\n");
          pthread_exit(NULL);
      }
  
      pthread_exit(NULL);
  }
  
  void *consumer(void *arg)
  {
  
      if (sem_wait(&amp;fill)) { /* wait */
          printf("Error: sem wait fail\n");
          pthread_exit(NULL);
      }
  
      i--;
      *(int *) arg = buf[i].data;
  
      if (sem_post(&amp;empty)) { /* post */
          printf("Error: sem wait fail\n");
          pthread_exit(NULL);
      }
      pthread_exit(NULL);
  }
  </code></pre>
  
  <p><br>
  Output without sleep statement:<br></p>
  
  <pre><code>Selection
  Producer : 1 | Consumer : 2 | Display : 3 | Exit : 0 || 1
  
  Producer
  Enter data: 11
  
  Selection
  Producer : 1 | Consumer : 2 | Display : 3 | Exit : 0 || 3
  
  Display
  buf[0] = 11
  
  Selection
  Producer : 1 | Consumer : 2 | Display : 3 | Exit : 0 || 2
  
  Consumer
  Consume data: 4196464
  </code></pre>
  
  <p>If sleep statement is added in consumer block then expected output(in our case 11) is obtain. <br>Due to sleep statement insertion, consumer thread get enough time to complete its execution compared to case 2 statements of switch and provide expected output.</p>