【发布时间】:2014-08-04 00:11:00
【问题描述】:
我有 N 个线程执行各种任务,这些线程必须定期与线程屏障同步,如下图所示,有 3 个线程和 8 个任务。 ||表示时间障碍,所有线程必须等到完成8个任务才能重新开始。
Thread#1 |----task1--|---task6---|---wait-----||-taskB--| ...
Thread#2 |--task2--|---task5--|-------taskE---||----taskA--| ...
Thread#3 |-task3-|---task4--|-taskG--|--wait--||-taskC-|---taskD ...
我找不到可行的解决方案,认为 Semaphores http://greenteapress.com/semaphores/index.html 的小书很有启发性。我想出了一个使用下面显示的 std::atomic 的解决方案,它“似乎”正在使用三个 std::atomic。 我担心我的代码在极端情况下崩溃,因此引用了动词。那么您能否分享有关验证此类代码的建议?你有更简单的防呆代码吗?
std::atomic<int> barrier1(0);
std::atomic<int> barrier2(0);
std::atomic<int> barrier3(0);
void my_thread()
{
while(1) {
// pop task from queue
...
// and execute task
switch(task.id()) {
case TaskID::Barrier:
barrier2.store(0);
barrier1++;
while (barrier1.load() != NUM_THREAD) {
std::this_thread::yield();
}
barrier3.store(0);
barrier2++;
while (barrier2.load() != NUM_THREAD) {
std::this_thread::yield();
}
barrier1.store(0);
barrier3++;
while (barrier3.load() != NUM_THREAD) {
std::this_thread::yield();
}
break;
case TaskID::Task1:
...
}
}
}
【问题讨论】:
-
既然知道信号量,那么使用信号量有什么问题呢?
-
C++11 标准库中没有原生 std::semaphore,所以你必须使用 std::mutex 和 std::condition_variable。
-
这有帮助吗? stackoverflow.com/questions/8115267/…我可以通过一票关闭重复,但我确定这是否是同一个问题。
-
@R.MartinhoFernandes 有趣的问题是我们是否需要旋转解决方案。通常情况下,屏障不会以这种方式实现,因为预计某些线程将不得不等待其他线程完成,而我们不想在此期间因忙于等待而阻塞核心。基于
condition_variable将等待线程发送到睡眠的解决方案在这里似乎更合适。 -
你是对的,这是关键问题。我的建议是一个旋转解决方案,所以它可能没有那么有效。我将切换到找到 here 的 [condition_variable]。
标签: multithreading c++11