0

I have a Standard Producer Consumer problem for bounded buffer.Whenever i give unequal number of producer or consumer the Program does not terminate. I have limited the number of insertion or deletion to 50 I would like to know why the above problem occurs and ways to fix it

 #include<stdio.h>
 #include<pthread.h>  //Header for creating Posix Threads;
 #include<semaphore.h> 
 #include<stdlib.h>
 #define MAX 20

 typedef struct shared_buffer
  {
     int arr[20];
     int i; 
  }buffer;   

  buffer b;         //Fixed Length buffer shared memory

sem_t full,empty;    //Counting semaphores full->no of slots filled  empty ->no of slots        empty
pthread_mutex_t mutex; //mutual exclusion for critcal section
int flag=1,cnt=0;      
void * producer(void * arg)   //Producer threads method
{
  int index;   //thread Id
  index=(int)arg;

  while(flag)
   {

     sem_wait(&empty);        //will check if slot available and decrement empty count
     pthread_mutex_lock(&mutex);   //acquiring lock on process
     b.arr[b.i]=rand()%100;        //critcal section
     printf("\n Process %d Produced :%d",index,b.arr[b.i]);
     b.i++;
         cnt++;                //critcal section ends
     pthread_mutex_unlock(&mutex); //realeasing lock 
     sem_post(&full);              //increment full count 
         usleep(rand()%100);           //sleep for random time

   }
 }

 void * consumer(void * arg)
 {
  int index;
  index=(int)arg;
  while(flag)
  {   
     sem_wait(&full);                  //will check if buffer is not empty
     pthread_mutex_lock(&mutex); 
     b.i--;                           //critical section
     printf("\n Process %d consumed :%d",index,b.arr[b.i]);
     cnt++;                      //critical section ends
     pthread_mutex_unlock(&mutex);  //release lock
     sem_post(&empty);             //increment count of empty slots
     usleep(rand()%100);
  }
 }


int main(int argc,char * argv[])
{
   pthread_t Pid,Cid;
   int P,C,index,size;
   b.i=0;
 if(argc<4)
 {
    printf("Error.Usage : ./filename.out <no of producer> <no of consumer> <Buffer     Size(<=15)> \n");
   exit(0);
 }
  P=atoi(argv[1]);
  C=atoi(argv[2]);
  size=atoi(argv[3]);
  sem_init(&full,0,0);              //number of slots filled is 0
  sem_init(&empty,0,size);         //number of empty slots is buffer size
  pthread_mutex_init(&mutex,NULL);

  for (index=0;index<C;index++)     //creating C number of consumer
  {
     pthread_create(&Cid,NULL,consumer,index);
  }
  for (index=0;index<P;index++)    //creating P number of producer
  {
    pthread_create(&Pid,NULL,producer,index);
  }
while(cnt<=50)                    //maximum 50 operations allowed
   usleep(200);
   flag=0;
   printf("phew!Successful");
   pthread_exit(NULL);
   return 1;

}

2 Answers2

0

Here are some clues (not full answer):

First thing that bugging me is that you are overwriting your pthread_t references in your loops. But it is OK since you don't use them afterwards.

Second thing is that you misplaced the pthread_exit: there should be at the end of the threads you created:

void * consumer_producer(void * arg)
{
    // ...
    while(flag)
    {
      // ...
    }
    pthread_exit(NULL);
}
n0p
  • 3,399
  • 2
  • 29
  • 50
  • Note that `pthread_t` references could be used in your `main` to track thread terminations via `pthread_join()` – n0p Feb 24 '14 at 16:28
  • Those references that you say in the for loop. Dont they act as ids for individual threads Doesnt the pthread_exit in main cause all other threads to be terminated before terminating main itself – Rajeev Sebastian Feb 24 '14 at 16:35
0

I guess you have a race condition. It is possible that a thread is waiting when flag is set to 0. Other threads possibly catch that state and return, thus the waiting thread is waiting forever.

Matthias
  • 8,018
  • 2
  • 27
  • 53
  • But the race condition should occur even when i have equal number of producer and consumer right – Rajeev Sebastian Feb 24 '14 at 17:13
  • I may, but the changes are higher in case of an uneven number, since then you have unbalanced calles. – Matthias Feb 24 '14 at 17:50
  • so how about if i change the flag value in the critical section itself – Rajeev Sebastian Feb 27 '14 at 16:08
  • How do you want to do that - the flag is set asynchronously. You may use local flags, that are set to the value of the global flag within the critical section. However, it provides no guarantee that all products are really consumed. – Matthias Feb 28 '14 at 18:06