我有一个程序,该程序启动N个线程(异步/将来)。我希望主线程设置一些数据,然后所有线程都应该走,而主线程等待所有其他线程完成,然后需要循环。
我有atm就是这样
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();
}
}
但是我看不到主线程或其他线程正在等待的任何迹象!知道我在做什么错或者我怎么做吗?
答案 0 :(得分:0)
有两个问题。首先,您要在第一个工作人员醒来后立即设置bDone
。因此,主线程立即唤醒并开始准备下一个数据集。您想让主线程等到所有工作人员完成 处理数据。其次,当工作人员完成处理时,它会循环并立即检查bRun
。但是,它无法判断bRun == true
是否意味着下一个数据集已准备好,或者 last 数据集是否已准备好。您要等待下一个数据集。
类似的事情应该起作用:
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();
}
}
}
请注意,此解决方案还不够完善。如果一个工作程序遇到异常,则主线程将挂起(因为死掉的工作程序永远不会减少nWorkerCount
)。您可能需要一种策略来应对这种情况。
顺便说一句,此模式称为barrier
。