首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++:如何在UI线程和工作线程之间使用std::condition_variable

C++:如何在UI线程和工作线程之间使用std::condition_variable
EN

Stack Overflow用户
提问于 2017-10-07 13:38:22
回答 1查看 1.7K关注 0票数 0

我正在尝试使用来自C++11C++11来处理UI线程和工作线程之间的数据事务。

形势:

m_calculated_value是一个在复杂逻辑之后计算出来的值。这在UI线程的事件触发器上是必需的。UI线程调用MyClass::GetCalculatedValue来获取m_calculated_value的值,该值需要由工作线程函数(即MyClass::ThreadFunctionToCalculateValue )计算。

代码:

代码语言:javascript
复制
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吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-07 16:29:12

请看下面的示例:

变量

在下面的示例代码中注释中注意到对有关代码的更改。您可能需要考虑使用与cppreference.com示例中相同的“握手”来同步计算新值( UI线程有等待/通知,工作线程有通知/等待)。

在条件变量等待之前,需要锁定锁。等待将解锁,等待通知,然后锁定并使用谓词函数,检查是否就绪,如果没有就绪(虚假唤醒),重复循环。

在notify_one之前,锁应该被解锁,否则等待会被唤醒,但是无法获得一个锁(因为它仍然被锁定)。

代码语言:javascript
复制
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();
}

或替代办法:

代码语言:javascript
复制
// 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();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46620817

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档