【发布时间】:2015-11-05 07:59:28
【问题描述】:
我以这种方式使用 std::condition_variable :
void wait()
{
std::unique_lock<std::mutex> lock(m_stateCompletedMutex);
m_waitCondition.wait(lock, [this](){return (m_state == STATE_COMPLETED);});
}
对此我很满意,但现在我想在“等待期间”执行一些代码(我不知道我是否可以这样说,但这就是想法)例如更新GUI 或增加等待计数器,或其他任何东西。
说我们正在使用 Qt,我尝试过这样的事情:
void wait()
{
std::unique_lock<std::mutex> lock(m_stateCompletedMutex);
while (m_state != STATE_COMPLETED)
{
m_waitCondition.wait(lock);
// Use this an example, it could be any code, executed in the waiting thread
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
}
}
这里的目标是在我们等待工作线程完成时保持 GUI 响应(至少对系统事件,而不是用户输入)。
我对这段代码有两个问题:
1/ 是这样做的好方法,还是有更好的方法在“等待时”执行代码
2/“等待代码”(在我的示例中调用 qApp->processEvents)多久执行一次?它依赖于系统吗?还是取决于当前的 CPU 负载或其他任何东西?或者我应该使用 m_waitCondition.wait_for 来确保最低频率调用?
关于第 2 点/,我已经测试过监控它(使用 std::chrono::high_resolution_clock),在我的应用程序中延迟似乎在 200 毫秒到 4000 毫秒之间,我认为这是一个很大的范围。
【问题讨论】:
-
对于“等待时”执行代码,您需要创建新线程或进程。设计可以有 10 个线程,其中 9 个在给定时刻等待。通常
.wait()仅在对应的.notify调用后返回。 虚假唤醒实际上很少见。 -
“虚假唤醒实际上很少见”:我也是这么想的。但是我已经用经过时间计数器测试了一个输出到控制台(而不是我的示例中的 qApp->processEvents 调用),并且消息大约每 200 毫秒到 4000 毫秒被写入控制台。
-
也就是说,您的
.wait()每 200-4000 毫秒唤醒一次只是虚假的(没有.notify()在其他线程中调用)? -
在我的示例中,qApp->processEvents 每 200-4000 毫秒调用一次?没有任何 notify()。
-
最简单的解决方案不是使用条件变量,而是让你的代码在它完成它正在做的任何事情时发出一个信号。信号发射可以通过 API 作为模板类型用户提供的仿函数的调用公开。
标签: multithreading qt c++11 condition-variable stdthread