线程同步pthread条件变量
thread sync with pthread conditional variable
使用pthread条件变量进行线程同步时遇到一些问题。我有一个线程解析提取一些值的消息,另一个线程使用提取的值增加一些变量。我使用pthread条件变量来同步这两个线程。第一个线程看起来像下面的片段:
if(parse_ok){
pthread_mutex_lock(&q_mutex);
q = extract_value();
q_changed = true;
printf("...awaken");
pthread_cond_signal(&q_cond_var);
pthread_mutex_unlock(&q_mutex);
}
工作线程看起来像下面的片段:
while(true){
pthread_mutex_lock(&q_mutex);
if( !q_changed ){
std::cout<<"waiting..!"<<std::endl;
pthread_cond_wait(&q_cond_var, &q_mutex);
}
if(q_changed){
q_changed = false;
_actual_q += q;
_total_q += q;
_quant_q += q/_fixed_quantity;
}
pthread_mutex_unlock(&q_mutex);
}//END of while TRUE
此代码在大多数情况下都能正常工作。有时,当我一条接一条地收到很多信息时,睡眠线程会跳过一些唤醒。我是否需要一些信号量来阻止接收线程,直到工作线程完成它的工作?怎样提前谢谢。
这里有几件事可能会刺痛你:
a) printf和cout不是线程安全的,因此它们的输出可能无法反映代码中等待和唤醒的实际顺序。
b) 在您的代码中,虚假唤醒无法得到有效处理。我会将if( !q_changed )
条件更改为while (!q_changed)
,以最大限度地减少在错误唤醒条件变量时重新等待所需的时间(这也将允许您删除最后一个if (q_changed)
条件块)。
EDIT(基于@EOF等人的评论):如果使用现代C++/C实现(我认为你不是,因为你使用的是pthreads),那么b)很可能是你的问题。这种情况下的竞争是等待线程可以唤醒然后解锁互斥锁。与此同时,信令线程获取锁和信号。由于你没有等待这种情况,你没有得到信号。然而,请注意,这不是问题——您仍然处理数据——只是在这种情况下,您没有向cout输出"等待"消息。
按照代码的编写方式,不能保证第二个工作线程每次第一个线程发出信号时都会处理新的输入。不过,您可以扩展q_changed
变量的使用,以确保这种情况发生。
将您的第一个线程更改为:
if(parse_ok){
pthread_mutex_lock(&q_mutex);
while (q_changed) // Always wait in in loop
pthread_cond_wait(&q_cond_var, &q_mutex);
q = extract_value();
q_changed = true;
pthread_cond_signal(&q_cond_var);
pthread_mutex_unlock(&q_mutex);
}
然后将您的第二个工作线程更改为:
while(true){
pthread_mutex_lock(&q_mutex);
while( !q_changed ) // Always wait in a loop
pthread_cond_wait(&q_cond_var, &q_mutex);
q_changed = false;
_actual_q += q;
_total_q += q;
_quant_q += q/_fixed_quantity;
pthread_cond_signal(&q_cond_var);
pthread_mutex_unlock(&q_mutex);
}
相关文章:
- 基于模板值的条件变量
- 没有超时的C++条件变量
- 在条件变量中触发错误信号的频率是多少
- 使用不变量来确定二分搜索中的边界条件
- 在通知提升间处理条件变量时未按住锁会导致问题
- 通知条件变量后使用互斥锁
- 如何改进一堆在已知值范围内评估变量的 else-if 条件?
- 滥用条件变量
- 升压插值条件变量可以虚假唤醒吗?
- 根据模板类型有条件地删除变量
- 子线程中的条件变量等待停止主线程中的执行
- 如何使用 SFINAE 在方法调用中有条件地定义变量?
- 条件变量基本示例
- 正在连接的等待条件变量的线程会发生什么情况?
- C++11如何在1个线程中使用条件变量处理2个线程安全队列
- 当线程处理不同的类时,应该在哪里声明条件变量、互斥对象
- 为什么在同一条件变量上使用多个互斥锁会使此代码崩溃?
- 条件变量:wait_for.gcc错误
- 如何"stop"正在等待条件变量的分离线程?
- 调用一个小函数两次(例如在if条件和主体中)比将结果存储在局部变量中更可取