c++ - 使用 C++ notify_all() 避免饥饿

标签 c++ multithreading c++11 design-patterns

我的屏障同步场景是这样的:

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/

相关文章:

c++ - 读取文件的未知部分到 vector

python - 无法在Python中创建新线程

c++ - Producer Consumer 使用 intel-pin 内线程

python - 使用 pyzmq 通过 Zeromq 套接字快速传输 Python 字典和列表有哪些选项?

c++ - CRTP -- 访问不完整的类型成员

c++ - T declval() 而不是 T && declval() for common_type

android - 如何将 C++ 源代码解析为 obj?

c++ - leptonica - 获取尺寸(高度/宽度)

C++:不确定类 - 类管理器关系

c++ - 为什么 `std::initializer_list` 不提供下标运算符?