Проблема в том, что вы используете переменную условия неправильно. Условная переменная - это просто механизм уведомления, а не флаг. Он не имеет внутреннего состояния, кроме списка потоков, ожидающих в данный момент. Следовательно, если main()
фактически не выполняется до вызова pthread_cond_wait()
, когда другие потоки вызывают pthread_cond_signal()
, то сигнал теряется, и main()
будет ждать вечно.
Вам необходимо использовать отдельный флаг, связанный с условной переменной. main()
может затем проверить этот флаг и ждать только, если флаг не установлен. Кроме того, он должен проверять этот флаг в цикле, чтобы гарантировать, что обрабатываются «ложные пробуждения», где pthread_cond_wait()
возвращает без соответствующего сигнала. То же самое относится к уведомлению между threadOne
и threadTwo
.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
pthread_mutex_t gLock;
pthread_cond_t gCondition;
int gFlag=0;
pthread_mutex_t mLock;
pthread_cond_t mCondition;
int mFlag=0;
void initialize()
{
pthread_mutex_init(&gLock, NULL);
pthread_cond_init (&gCondition, NULL);
pthread_mutex_init(&mLock, NULL);
pthread_cond_init (&mCondition, NULL);
}
void * threadOne(void * msg)
{
printf("%s \n",(char*) msg);
printf("before conditional wait\n");
pthread_mutex_lock(&gLock);
while(!gFlag)
{
pthread_cond_wait(&gCondition,&gLock);
}
pthread_mutex_unlock(&gLock);
printf("i am again in thread 1\n");
pthread_mutex_lock(&mLock);
mFlag=1;
pthread_cond_signal(&mCondition);
pthread_mutex_unlock(&mLock);
}
void * threadTwo(void * msg)
{
printf("%s\n",(char*)msg);
printf("before conditional release\n");
pthread_mutex_lock(&gLock);
gFlag=1;
pthread_cond_signal(&gCondition);
pthread_mutex_unlock(&gLock);
printf("i am again in thread 2\n");
}
int main()
{
pthread_t thread1;
pthread_t thread2;
char * msg1="I am in thread 1";
char * msg2="I am in thread 2";
initialize();
pthread_create(&thread1,NULL,threadOne,(void*) msg1);
pthread_create(&thread2,NULL,threadTwo,(void*) msg2);
pthread_mutex_lock(&mLock);
while(!mFlag)
{
pthread_cond_wait(&mCondition,&mLock);
}
pthread_mutex_unlock(&mLock);
printf("main exits here");
return 0;
}