升压条件变量
Boost condition variable
我想使用boost条件变量作为同步机制,但是在这种情况下:
boost::condition_variable cond;
boost::mutex mutex;
void worker_func()
{
cond.notify_all();
std::cout << "After notify" << std::endl;
}
void main()
{
boost::mutex::soped_lock lock(mutex);
boost::thread work(worker_func);
boost::this_thread::sleep_for(boost::chrono::milliseonds(500));
cond.wait(lock); // here is deadlock
}
当我们在等待条件之前触发条件时,就会发生死锁。如果有一个很好的解决方案来编写包装器,提供bool原子,"记住"先前触发的条件,或者有其他更好的方法来做到这一点?
包装器示例:
class Cond_wrap
{
private:
boost::condition_variable cond;
boost::mutex mutex;
bool work_to_do;
public:
Cond_wrap()
{
boost::mutex::scoped_lock(mutex);
work_to_do = false;
}
void notify_all()
{
boost::mutex::scoped_lock(mutex);
work_to_do = true;
cond.notify_all();
}
void wait()
{
boost::mutex::scoped_lock lock(mutex);
if(!work_to_do)
{
cond.wait(lock);
work_to_do = true;
}
else
{
return;
}
}
bool timed_wait(unsigned int timeout)
{
boost::mutex::scoped_lock lock(mutex);
if(!work_to_do)
{
if(cond.timed_wait(lock, boost::chrono::milliseonds(timeout)))
{
work_to_do = true;
return true;
}
else
{
return false;
}
}
else
{
return false;
}
};
Cond_wrap condition_wrap;
void worker_func()
{
{
condition_wrap.notify_all();
}
std::cout << "After notify" << std::endl;
}
int main()
{
boost::thread work(worker_func);
work.detach();
{
boost::this_thread::sleep_for(boost::chrono::milliseonds(500));
condition_wrap.wait();
//there is work to do
}
return 0;
}
条件变量不是这样工作的。条件变量应该有一个相关联的条件。这个条件是在持有互斥锁的情况下求值的,因此不可能出现竞争,因此不需要等待。
请注意,此条件还需要考虑虚假唤醒的可能性。
还应该从持有锁的线程通知条件变量。在锁被持有的情况下生成新线程可能不是一个好主意。我喜欢用大括号来清楚地说明锁定代码的作用域。
boost::condition_variable cond;
boost::mutex mutex;
bool work_to_do = false;
void worker_func()
{
{
boost::mutex::scoped_lock lock(mutex);
work_to_do = true,
cond.notify_all();
}
std::cout << "After notify" << std::endl;
}
int main()
{
boost::thread work(worker_func);
{
boost::mutex::scoped_lock lock(mutex);
boost::this_thread::sleep_for(boost::chrono::milliseonds(500));
while (!work_to_do)
cond.wait(lock); // no deadlock
//there is work to do
work_to_do = false;
}
}
请注意,在我的代码中,work_to_do
变量总是与持有的锁一起使用,对notify_all()
的调用也是如此。另外,请注意cond.wait()
是在循环中调用的,因此虚假的唤醒不会破坏乐趣。
p。对void main()
说不
与windows事件不同,条件变量没有任何状态,因为它是用于等待和通知的机制。也可能有虚假的唤醒。
必须将一些状态与条件变量关联起来。示例见http://en.cppreference.com/w/cpp/thread/condition_variable。
要使用条件变量,需要具备3个条件:
条件变量、互斥锁和变量。
操作其他两个元素时,锁住互斥锁。
当你想发送消息给等待者时,锁定互斥锁,设置变量,然后使用条件变量通知。(在某些情况下,在notify: check your docs之前解锁互斥锁)
当你想要获取消息时,锁定互斥锁,检查变量,等待条件。可能会有虚假的唤醒(请检查您的文档),所以当您唤醒时请重新检查变量。
这是基于c++ 11 std
条件变量的知识,因此有"check your docs"注释。
- 基于模板值的条件变量
- 没有超时的C++条件变量
- 在条件变量中触发错误信号的频率是多少
- 使用不变量来确定二分搜索中的边界条件
- 在通知提升间处理条件变量时未按住锁会导致问题
- 通知条件变量后使用互斥锁
- 如何改进一堆在已知值范围内评估变量的 else-if 条件?
- 滥用条件变量
- 升压插值条件变量可以虚假唤醒吗?
- 根据模板类型有条件地删除变量
- 子线程中的条件变量等待停止主线程中的执行
- 如何使用 SFINAE 在方法调用中有条件地定义变量?
- 条件变量基本示例
- 正在连接的等待条件变量的线程会发生什么情况?
- C++11如何在1个线程中使用条件变量处理2个线程安全队列
- 当线程处理不同的类时,应该在哪里声明条件变量、互斥对象
- 为什么在同一条件变量上使用多个互斥锁会使此代码崩溃?
- 条件变量:wait_for.gcc错误
- 如何"stop"正在等待条件变量的分离线程?
- 调用一个小函数两次(例如在if条件和主体中)比将结果存储在局部变量中更可取