Today I learn pthread,I write a toy example about the producer and consumer problem.But I find the program's action is different when I put the pthread_cond_signal in a loop or not in a loop.Here is the original code.
#include <pthread.h>
#include <stdio.h>
int good_count = 0;
int total = 0;
pthread_mutex_t mt;
pthread_cond_t cv;
volatile int producer_wait = 1;
void* produce()
{
pthread_mutex_lock(&mt);
printf("Producer Wait;\n");
producer_wait = 1;
pthread_cond_wait(&cv, &mt);
producer_wait = 0;
printf("Received a signal\n");
pthread_mutex_unlock(&mt);
pthread_exit(NULL);
}
void* consume()
{
pthread_mutex_lock(&mt);
while(producer_wait)
{
pthread_cond_signal(&cv);
sleep(1);
}
//pthread_cond_signal(&cv);
pthread_mutex_unlock(&mt);
pthread_exit(NULL);
}
int main()
{
pthread_t threads[2];
pthread_attr_t attr;
/*initialize mutex and cond */
pthread_mutex_init(&mt, NULL);
pthread_cond_init(&cv, NULL);
/*initialize thread attribute*/
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&threads[0], &attr, produce, NULL);
pthread_create(&threads[1], &attr, consume, NULL);
int i;
for (i = 0; i < 2; i++) {
pthread_join(threads[i], NULL);
}
pthread_attr_destroy(&attr);
pthread_mutex_destroy(&mt);
pthread_cond_destroy(&cv);
pthread_exit(NULL);
}
The producer thread block in pthread_cond_wait(&cv, &mt),the consumer thread call pthread_cond_signal(&cv) in a while loop does not take effect.But if I modify the consume() function code like this,then it take effects.
void* consume()
{
pthread_mutex_lock(&mt);
/*while(producer_wait)
{
pthread_cond_signal(&cv);
sleep(1);
}*/
pthread_cond_signal(&cv);
pthread_mutex_unlock(&mt);
pthread_exit(NULL);
}
I am very puzzled, hoping to get answers!
I modify the consume function,move pthread_mutex_lock(&mt) and pthread_mutex_unlock(&mt) into the while loop,and comment the sleep(1), the consumer can release the mutex.In this way,the producer thread can receive the signal. But if I uncomment sleep(1),the producer thread can't receive the signal.Why?
void* consume()
{
while(producer_wait)
{
pthread_mutex_lock(&mt);
pthread_cond_signal(&cv);
//sleep(1);
pthread_mutex_unlock(&mt);
}
pthread_exit(NULL);
}
the consumer thread