#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
static pthread_cond_t
cond=PTHREAD_COND_INITIALIZER; /*statically initialize the condition variable
*cond* */
static pthread_mutex_t
mtx=PTHREAD_MUTEX_INITIALIZER;/*statically initialize the mutex *mtx* */
static int prod=0;
static int basic=100;
static int actual_prod=250;
static int temp;
void * producer() /*producer thread */
{
int i;
temp=actual_prod; /*store the
actual_prod value in temp coz we are gonna change actual_prod in consumer */
for(i=1;i<=temp;i++)
{
pthread_mutex_lock(&mtx); /*lock the
mutex */
prod++;
pthread_mutex_unlock(&mtx);/*unlock
the mutex*/
if(prod==basic) /*if producer has
produced *basic* units , send a signal to consume */
{
printf("producer produced %d
units\n",prod);
pthread_cond_signal(&cond); /*send a
signal , so that pthread_cond_wait() returns and consumer will be able to
consume */
}
/*suppose , u wanna produce 250 units or
50 units , in that case consumer should be still able to consume everything,
lets assume actual_prod=50, then at this
point prod=50 ,actual_prod=50 , basic=100...condition satisfies so send a
signal . If actual_prod is 250, for understanding this case check consumer
thread*/
else if((prod==actual_prod) &&
(actual_prod < basic))
{
printf("producer produced %d
units\n",actual_prod);
pthread_cond_signal(&cond);
}
}//for
printf("prod=%d\n",prod);
/*print the final value of prod ...should be zero ie all produced units must be
consumed */
exit(1); /*terminates all threads */
}
void *consumer()
{
for(;;){
pthread_mutex_lock(&mtx); /*lock the
mutex */
/*for actual_prod =100 , by the time
pthread_cond_wait() receives a signal , prod will be 100..so wont wait */
/*Assume , that context switch occurs
when prod =90 , but actual_prod=200, then it will wait */
/*but take for ex , prod=90 but
actual_prod is also 90, then it wont wait coz second condition will be false*/
while((prod!=basic) &&
(prod!=actual_prod))
pthread_cond_wait(&cond,&mtx);
if(actual_prod<basic) /* to consume
the left out units produced for ex , if actual_prod is 250 ,then the last 50
units */
{printf("consumer consumed %d
units\n",prod);
prod=prod-actual_prod;
actual_prod-=prod; /*this is for
decrementing the value of actual_prod , used when actual_prod is greater than
basic , but is not a multiple of basic . for ex actual_prod = 350*/
}
else if (prod == basic){ /* when
actual_prod is a multiple of basic */
printf("consumer consumed %d
units\n",prod);
prod=prod-basic;
actual_prod-=basic;
}
else
continue;
pthread_mutex_unlock(&mtx);
/*explicitly unlock the mutex */
}
}
int main()
{
pthread_t t1,t2;
int status;
status=pthread_create(&t1,NULL,consumer,NULL);
status=pthread_create(&t2,NULL,producer,NULL);
pthread_join(t2,NULL); /*wait for
producer */
pthread_join(t1,NULL);/*wait for
consumer */
return 0;
}
0 Comments