我正在尝试使用来自C++11的C++11来处理UI线程和工作线程之间的数据事务。
形势:
m_calculated_value是一个在复杂逻辑之后计算出来的值。这在UI线程的事件触发器上是必需的。UI线程调用MyClass::GetCalculatedValue来获取m_calculated_value的值,该值需要由工作线程函数(即MyClass::ThreadFunctionToCalculateValue )计算。
代码:
std::mutex m_mutex;
std::condition_variable m_my_condition_variable;
bool m_value_ready;
unsigned int m_calculated_value;
// Gets called from UI thread
unsigned int MyClass::GetCalculatedValue() {
std::unique_lock<std::mutex> lock(m_mutex);
m_value_ready = false;
m_my_condition_variable.wait(lock, std::bind(&MyClass::IsValueReady, this));
return m_calculated_value;
}
bool MyClass::IsValueReady() {
return m_value_ready;
}
// Gets called from an std::thread or worker thread
void MyClass::ThreadFunctionToCalculateValue() {
std::unique_lock<std::mutex> lock(m_mutex);
m_calculated_value = ComplexLogicToCalculateValue();
m_value_ready = true;
m_my_condition_variable.notify_one();
}问题:
但问题是m_my_condition_variable.wait再也不会回来了。
问题:
我在这里做错什么了?
让UI线程等待来自工作线程的条件变量信号是正确的方法吗?如何摆脱condition_variable不会因为工作线程函数中的错误而触发的情况?有什么办法可以让我在这里暂停一下吗?
试图理解它的工作原理:
我在许多例子中看到,它们使用一个while循环来检查condition_var.wait周围的布尔变量的状态。在变量上循环的意义是什么?当从其他线程调用m_my_condition_variable时,我不能期望notify_one退出wait吗?
发布于 2017-10-07 16:29:12
请看下面的示例:
变量
在下面的示例代码中注释中注意到对有关代码的更改。您可能需要考虑使用与cppreference.com示例中相同的“握手”来同步计算新值( UI线程有等待/通知,工作线程有通知/等待)。
在条件变量等待之前,需要锁定锁。等待将解锁,等待通知,然后锁定并使用谓词函数,检查是否就绪,如果没有就绪(虚假唤醒),重复循环。
在notify_one之前,锁应该被解锁,否则等待会被唤醒,但是无法获得一个锁(因为它仍然被锁定)。
std::mutex m_mutex;
std::condition_variable m_my_condition_variable;
bool m_value_ready = false; // init to false
unsigned int m_calculated_value;
// Gets called from UI thread
unsigned int MyClass::GetCalculatedValue() {
std::unique_lock<std::mutex> lock(m_mutex);
m_my_condition_variable.wait(lock, std::bind(&MyClass::IsValueReady, this));
m_value_ready = false; // don't change until after wait
return m_calculated_value;
} // auto unlock after leaving function scope
bool MyClass::IsValueReady() {
return m_value_ready;
}
// Gets called from an std::thread or worker thread
void MyClass::ThreadFunctionToCalculateValue() {
std::unique_lock<std::mutex> lock(m_mutex);
m_calculated_value = ComplexLogicToCalculateValue();
m_value_ready = true;
lock.unlock(); // unlock before notify
m_my_condition_variable.notify_one();
}或替代办法:
// Gets called from an std::thread or worker thread
void MyClass::ThreadFunctionToCalculateValue() {
{ // auto unlock after leaving block scope
std::lock_guard<std::mutex> lock(m_mutex);
m_calculated_value = ComplexLogicToCalculateValue();
m_value_ready = true;
} // unlock occurs here
m_my_condition_variable.notify_one();
}https://stackoverflow.com/questions/46620817
复制相似问题