【发布时间】:2021-06-10 01:57:03
【问题描述】:
我使用conditional_variable::notify_all()唤醒一个等待线程(只有一个线程在等待unique_lock确实)。
这段代码sn-p大部分时候运行良好,但是日志文件(详见下文)表明,在新创建的线程全部返回后,父线程无法获取unique_lock。
如果能在这个问题上得到一些帮助,我将不胜感激。
这里是相关代码sn-p:
void MainWindow::deployAction(void)
{
std::condition_variable cvRunOver;
std::mutex mtxRunOver;
std::unique_lock <std::mutex> ulkRunOver(mtxRunOver);
QString workerThreadRes;
std::thread workThread([&]()
{
workThread.detach();
do_some_process_for_seconds();
cvRunOver.notify_all();
LOG(INFO)<<"to leave the subthread";
google::FlushLogFiles(google::GLOG_INFO);
return;
});
while (cvRunOver.wait_for(ulkRunOver, std::chrono::milliseconds(100)) == std::cv_status::timeout)
{
qApp->processEvents();
auto curTim = std::chrono::steady_clock::now();
std::chrono::duration<float> escapedTim= curTim-lastTim;
if(std::chrono::duration_cast<std::chrono::seconds>(escapedTim).count()>=5)
{
LOG(INFO) << "processEvents()";
google::FlushLogFiles(google::GLOG_INFO);
lastTim = curTim;
}
}
LOG(INFO) << "get lock and continue to run";
google::FlushLogFiles(google::GLOG_INFO);
}
以下是程序无法正常运行时的相关日志:
Log line format: [IWEF]hh:mm:ss.uuuuuu threadid file:line] msg
20:19:14.638686 272568 mainwindow.cpp:208] to leave the subthread
20:19:17.669246 10256 mainwindow.cpp:221] processEvents()
20:19:22.678846 10256 mainwindow.cpp:221] processEvents()
20:19:17.669246 10256 mainwindow.cpp:221] processEvents()
20:19:22.678846 10256 mainwindow.cpp:221] processEvents()
20:19:17.669246 10256 mainwindow.cpp:221] processEvents()
20:19:22.678846 10256 mainwindow.cpp:221] processEvents()
20:19:17.669246 10256 mainwindow.cpp:221] processEvents()
...
【问题讨论】:
-
notify_all未排队。如果它在目标线程唤醒并运行时执行(这里:在 while 循环内),它将丢失。使用带有谓词的wait_for作为第三个参数来检测主线程实际上已发出“唤醒”信号并避免虚假唤醒。我被教导永远不要单独使用条件变量,而是使用带有一些信息的共享变量(例如,“正常”布尔值),例如“数据已准备好,您现在可以处理它”。 -
@zkoza 感谢您的澄清。能否请您给我一个简单的代码 sn-p 以使其更清晰?
-
在整段代码中
workThread是否持有ulkRunover?这意味着在工作时要持有锁,这是没有意义的。workThread在哪里修改共享状态?实际上,等待的共享状态在哪里? -
@David Schwartz >“在整个代码段中,workThread 是否持有 ulkRunover”?我想是这样。你看到Lamda函数的捕获子句是
&。所以workThread会在线程开始运行时获取这个锁。
标签: c++ qt c++11 condition-variable unique-lock