有人可以举一个 C++ 条件变量的例子,其中通知线程 B 的线程 A 必须在通知线程 B 后响应?
Posted
技术标签:
【中文标题】有人可以举一个 C++ 条件变量的例子,其中通知线程 B 的线程 A 必须在通知线程 B 后响应?【英文标题】:can someone give an example of C++ condition_varible where the thread A that notifies thread B has to respond after thread B is notified? 【发布时间】:2020-11-27 17:09:42 【问题描述】:例如,假设线程 B 正在等待一个条件变量,线程 A 通知线程 B。唤醒后,线程 B 做某事,然后通知 A,以便 A 做某事。我需要这个,因为如果线程 B 执行某些操作,我需要更新线程 A 中的 GUI。下面的代码是我脑海中的骨架。但是,我担心线程 B 可能会在线程 A 进入等待阶段之前通知 A。这是一个合理的担忧吗?在这种情况下,人们通常会怎么做?我在网上找到的所有condition_variable的例子都没有通知线程必须做依赖于通知线程的事情的情况。
std::mutex mtx;
std::condition_variable cond;
void threadA()
std::unique_lock<std::mutex> guard(mtx);
cond.notify_one();
cond.wait(guard, [&]()return some bool expression;)
// do something//
void threadB()
std::unique_lock<std::mutex> guard(mtx);
cond.wait(guard, [&]()return some bool expression;)
// do something//
cond.notify_one();
【问题讨论】:
您能具体说明some bool expression
的真正含义吗?而且,这个条件是如何在通知线程中设置的?这对于回答您的问题可能非常重要。
【参考方案1】:
类似的东西你可以试试。
std::mutex mtx;
std::condition_variable cond;
bool flag1 = false;
bool flag2 = false;
void threadA()
std::unique_lock<std::mutex> guard(mtx);
flag1 = true;
cond.notify_one();
std::unique_lock<std::mutex> guard(mtx);
while(!flag2)
cond.wait(guard, [&]()return some bool expression;)
// do something//
void threadB()
std::unique_lock<std::mutex> guard(mtx);
while(!flag1)
cond.wait(guard, [&]()return some bool expression;)
// do something//
std::unique_lock<std::mutex> guard(mtx);
flag2 = true;
cond.notify_one();
【讨论】:
【参考方案2】:使用std::atomic_flag
了解A
何时进入等待阶段。不要使用普通标志来避免数据争用。
#include <condition_variable>
#include <atomic>
std::mutex mtx;
std::condition_variable cond;
std::atomic_bool a_has_entered = false;
void threadA()
std::unique_lock<std::mutex> guard(mtx);
cond.wait(guard, [&]()a_has_entered = true;return some_bool_expression;);
// do something//
void threadB()
std::unique_lock<std::mutex> guard(mtx);
// do something//
while(!a_has_enterd);
cond.notify_one();
或者使用另一个conditon_variable
避免资源泄露,如下
std::mutex mtx, a_has_entered_guard_mtx;
std::condition_variable cond;
std::condition_variable cond_a_has_entered;
bool a_has_entered = false;
void threadA()
std::unique_lock<std::mutex> guard(mtx);
cond.wait(guard, [&]()std::lock_guard guard a_has_entered_guard_mtx;
a_has_entered = true;
cond_a_has_entered.notify_all();
return some_bool_expression;);
// do something//
void threadB()
std::unique_lock<std::mutex> guard(mtx);
// do something//
std::unique_lock a_has_entered_guard a_has_entered_guard_mtx;
cond_a_has_entered.wait(a_has_entered_guard, [&]()return a_has_entered;);
cond.notify_all();
【讨论】:
以上是关于有人可以举一个 C++ 条件变量的例子,其中通知线程 B 的线程 A 必须在通知线程 B 后响应?的主要内容,如果未能解决你的问题,请参考以下文章