我刚开始学习pthread条件变量。但是下面的代码没有按预期工作。
#include<iostream>
#include<pthread.h>
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t count_threshold_cv = PTHREAD_COND_INITIALIZER;
int count=0;
void *inc_func(void *arg)
{
pthread_mutex_lock(&mutex);
int c;
while(1)
{
cin>>c;
if(c==8){
pthread_cond_signal(&count_threshold_cv);break;}
}
cout<<"inc count reached 8"<<endl;
pthread_mutex_unlock(&mutex);
}
void *watch(void *arg)
{
pthread_mutex_lock(&mutex);
while(1){
pthread_cond_wait(&count_threshold_cv,&mutex);
break;
}
cout<<"This executed"<<endl;
pthread_mutex_unlock(&mutex);
}
int main()
{
pthread_t id[26];
pthread_create(&id[0],NULL,inc_func,NULL);
pthread_create(&id[1],NULL,watch,NULL);
int i;
for(i=0;i<2;i++)
{
pthread_join(id[i],NULL);
}
}
当输入为8时,此代码被挂起&#34; inc计数达到8?我无法理解。 我的理解在哪里错了?
答案 0 :(得分:3)
正确的解决办法是让watch
线程只等待它等待的条件还没有发生。
条件似乎是c == 8
(因为这是发出信号的信号),因此您需要将c
变量设为全局,以便在线程之间共享,然后更改{{ 1}}线程要做:
watch
现在首先运行哪个线程并不重要:您的代码无论哪种方式都是正确的。这是使用条件变量的正确方法:通常,服务员应该这样做:
void *watch(void *arg)
{
pthread_mutex_lock(&mutex);
while (c != 8) {
pthread_cond_wait(&count_threshold_cv, &mutex);
}
cout<<"This executed"<<endl;
pthread_mutex_unlock(&mutex);
return 0;
}
并且信号员应该这样做:
pthread_mutex_lock(&mutex);
while (!condition)
pthread_cond_wait(&cond, &mutex);
/* ... */
答案 1 :(得分:2)
这里重要的是pthread_cond_signal
将取消阻止该条件变量上阻塞的至少一个线程(意味着在同一条件变量上调用pthread_cond_wait
时当前被阻塞的线程) 。如果在一个线程调用pthread_cond_signal
时,没有其他线程等待该条件,那么基本上没有任何事情发生。
记住这一点,你的程序流程是这样的:
inc_func()
,它先锁定互斥锁; inc_func()
一直等待输入数字8,保持互斥锁始终锁定; inc_func
设法锁定互斥锁后,第二个线程被创建; 8
并且条件从线程1发出信号; 线程2还没有等待这个条件,所以它仍然被阻止试图锁定互斥锁; pthread_cond_wait
上阻塞。此时,线程1已经完成,线程2被阻塞等待条件被发出信号,主线程正在等待它完成。没有其他人可以发出这种情况的信号,所以你有一个悬念。
对于可能大部分时间 的快速修复,您可以尝试更改启动线程的顺序(启动watch
首先是线程)。但请记住并理解为什么我在可能和大多数时候使用粗体。
解决这个问题的正确方法是重新考虑你的锁定策略:在尽可能小的范围内锁定互斥锁,并在最短的时间内锁定它们。
答案 2 :(得分:1)
交换线程的执行顺序:
pthread_create(&id[1],NULL,watch,NULL);
pthread_create(&id[0],NULL,inc_func,NULL);
如果您首先运行thread0
,则thread1
永远不会超过互斥锁,因此它不会开始等待。比thread0
结束,只有thread1
执行pthread_cond_wait()
,但没有线程要做signal
。
如果您先启动thread1
,它会转到等待部分。