实际上,主要的场景是:从主线程有两个线程运行。通过使用条件变量,两个线程将运行并休眠,然后它将返回主线程。我的意思是我不想要不同的输出模式。只有一种模式:来自main-> thread1-> thread2-> main。 我已经为C线程编写了一个代码。它显示了我想要的结果,有时甚至没有。例如,输出是:
I am in thread 1
before conditional wait
I am in thread 2
before conditional release
i am again in thread 2
i am again in thread 1
main exits here
问题有时候“主要出口在这里”没有执行。请帮助我。需要注意的是我不能使用pthread_join()。我的代码如下所示
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
pthread_mutex_t gLock;
pthread_cond_t gCondition;
pthread_mutex_t mLock;
pthread_cond_t mCondition;
void initialize()
{
pthread_mutex_init(&gLock, NULL);
pthread_cond_init (&gCondition, NULL);
pthread_mutex_init(&mLock, NULL);
pthread_cond_init (&mCondition, NULL);
return;
}
void * threadOne(void * msg)
{
printf("%s \n",(char*) msg);
printf("before conditional wait\n");
pthread_mutex_lock(&gLock);
pthread_cond_wait(&gCondition,&gLock);
pthread_mutex_unlock(&gLock);
printf("i am again in thread 1\n");
pthread_mutex_lock(&mLock);
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);
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);
pthread_cond_wait(&mCondition,&mLock);
pthread_mutex_unlock(&mLock);
printf("main exits here");
return 0;
}
答案 0 :(得分:0)
问题是您正在错误地使用条件变量。条件变量只是一种通知机制,而不是标志。除了当前正在等待的线程列表之外,它没有内部状态。因此,如果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;
}