我的屏障同步场景是这样的:
a.线程在同步中向前迈出一步 - 即它们完成一个任务单元,然后等待所有其他线程执行相同的操作,然后当它们完成时,它们可以再次前进。
b.我有大量线程(大约 256 个)正在等待条件变量。当条件满足时,将发送 notify_all()
。
c. (出现饥饿风险的部分):在调用 notify_all()
之前,将 runnable
变量设置为 true
并设置计数器 - completed
- 设置为零。当线程完成其任务单元时,它会调用一个函数,该函数首先将 runnable
设置为 false
,然后递增 completed
变量 - 满足条件当completed
等于阈值(即需要完成一个任务单元的线程数)时,runnable
设置为true。
也就是说,我们像这样等待:
cond.wait(lck, runnable == true);
还有这个:
unique_lock<mutex> lck(runMut);
runnable = true;
cond.notify_all();
我担心的是,任何被唤醒的线程都可以完成其任务,然后在链中更下游的线程被唤醒之前调用 wait()
函数。当这个“较低”线程测试runnable
时,它会发现它设置为false
,因此返回 sleep 状态。
是否有设计模式或其他方法可以解决这个问题?
最佳答案
您可以使用两个条件变量。一个通知 worker 开始工作,一个通知 worker 已经完成。 IE。你的主线程将如下所示:
for (;;) {
running = 0;
done = 0;
cond_run.notify_all();
cond_done.wait(lck, []() { return done == threads; });
// handle results
}
你的工作线程将如下所示:
for (;;) {
cond_run.wait(lck, []() { return running < threads; });
++running;
lck.unlock();
// do work
lck.lock():
++done;
cond_done.notify_one();
}
关于c++ - 使用 C++ notify_all() 避免饥饿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33335167/