c++ - 使用单个条件变量暂停多个线程
问题描述
我有一个启动 N 个线程(异步/未来)的程序。我希望主线程设置一些数据,然后所有线程都应该去,而主线程等待所有其他线程完成,然后这需要循环。
我有自动取款机是这样的
int main()
{
//Start N new threads (std::future/std::async)
while(condition)
{
//Set Up Data Here
//Send Data to threads
{
std::lock_guard<std::mutex> lock(mrun);
bRun = true;
}
run.notify_all();
//Wait for threads
{
std::unique_lock<std::mutex> lock(mrun);
run.wait(lock, [] {return bDone; });
}
//Reset bools
bRun = false;
bDone = false;
}
//Get results from futures once complete
}
int thread()
{
while(otherCondition)
{
std::unique_lock<std::mutex> lock(mrun);
run.wait(lock, [] {return bRun; });
bDone = true;
//Do thread stuff here
lock.unlock();
run.notify_all();
}
}
但是我看不到任何主线程或其他线程在等待对方的迹象!知道我做错了什么或者我该怎么做吗?
解决方案
有几个问题。首先,您在bDone
第一个工作人员醒来后立即进行设置。因此主线程立即唤醒并开始准备下一个数据集。您希望主线程等待所有工作人员完成数据处理。其次,当工作人员完成处理时,它会循环并立即检查bRun
. 但它无法判断是否bRun == true
意味着下一个数据集已准备好或最后一个数据集是否已准备好。您想等待下一个数据集。
像这样的东西应该工作:
std::mutex mrun;
std::condition_variable dataReady;
std::condition_variable workComplete;
int nCurrentIteration = 0;
int nWorkerCount = 0;
int main()
{
//Start N new threads (std::future/std::async)
while(condition)
{
//Set Up Data Here
//Send Data to threads
{
std::lock_guard<std::mutex> lock(mrun);
nWorkerCount = N;
++nCurrentIteration;
}
dataReady.notify_all();
//Wait for threads
{
std::unique_lock<std::mutex> lock(mrun);
workComplete.wait(lock, [] { return nWorkerCount == 0; });
}
}
//Get results from futures once complete
}
int thread()
{
int nNextIteration == 1;
while(otherCondition)
{
std::unique_lock<std::mutex> lock(mrun);
dataReady.wait(lock, [&nNextIteration] { return nCurrentIteration==nNextIteration; });
lock.unlock();
++nNextIteration;
//Do thread stuff here
lock.lock();
if (--nWorkerCount == 0)
{
lock.unlock();
workComplete.notify_one();
}
}
}
请注意,此解决方案并不完整。如果一个worker遇到异常,那么主线程就会挂起(因为死掉的worker永远不会reduce nWorkerCount
)。您可能需要一种策略来处理这种情况。
顺便说一下,这种模式称为 a barrier
。
推荐阅读
- google-apps-script - 如何使用 Google App 脚本将 Google 电子表格的域权限设置为 RESTRICTED?
- selenium-chromedriver - 如何使用 selenium python 登录 HTTPS chrome 登录弹出窗口?
- python - 即使我遵循了文档,PYQT5 信号和插槽也无法正常工作
- firebase - Stream 内的 Flutter ListView.Builder 不更新
- r - 在R中安排一个复杂的数据集
- javascript - 有没有更快的方法从另一个网站获取 html 元素?
- javascript - 异步函数内的循环内的承诺
- mysql - 在 MySQL 上以二进制形式存储和检索 UUID 的高效/可扩展方式
- python - 将单选按钮与 tkinter 中的功能联系起来
- php - file_get_contents 和 $ _POST 的区别