首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++叉连接并行性阻塞

C++叉连接并行性阻塞
EN

Stack Overflow用户
提问于 2016-08-24 06:09:38
回答 2查看 5K关注 0票数 1

假设您希望并行运行一个节,然后合并回主线程,然后并行地返回到节,依此类推。类似于童年游戏的红灯绿灯。

我给出了一个我想要做的事情的例子,在这个例子中,我使用一个条件变量在开始时阻塞线程,但是希望并行地启动它们,但是在结束时阻止它们,这样就可以连续地输出它们。*=操作可能是一个跨越多秒的大得多的操作。重用线程也很重要。使用任务队列可能太重。

我需要使用某种阻塞结构,它不仅仅是一个普通的繁忙循环,因为我知道如何用繁忙的循环来解决这个问题。

英文本:

  1. 线程1创建10个被阻塞的线程。
  2. 线程1向所有线程发出启动信号(不阻塞彼此)
  3. 线程2-11处理它们的独占内存。
  4. 线程1等待2-11完成(可以在这里使用原子计数)。
  5. 线程2-11完成,如有必要,每个线程都可以通知1以检查其状态。
  6. 线程1检查它的条件并打印数组。
  7. 线程1重新发送2-11信号以再次处理,从2继续。

示例代码(从cplusplus.com上的示例改编而来):

代码语言:javascript
运行
复制
// condition_variable example
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
#include <atomic>

std::mutex mtx;
std::condition_variable cv;
bool ready = false;
std::atomic<int> count(0);

bool end = false;
int a[10];

void doublea (int id) {
  while(!end) {
    std::unique_lock<std::mutex> lck(mtx);
    while (!ready) cv.wait(lck);
    a[id] *= 2;
    count.fetch_add(1);
  }
}

void go() {
  std::unique_lock<std::mutex> lck(mtx);

  ready = true;
  cv.notify_all();
  ready = false; // Naive

  while (count.load() < 10) sleep(1);
  for(int i = 0; i < 10; i++) {
    std::cout << a[i] << std::endl;
  }

  ready = true;
  cv.notify_all();
  ready = false;
  while (count.load() < 10) sleep(1);
  for(int i = 0; i < 10; i++) {
    std::cout << a[i] << std::endl;
  }

  end = true;
  cv.notify_all();
}

int main () {
  std::thread threads[10];
  // spawn 10 threads:
  for (int i=0; i<10; ++i) {
    a[i] = 0;
    threads[i] = std::thread(doublea,i);
  }

  std::cout << "10 threads ready to race...\n";
  go();                       // go!

  return 0;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-25 01:23:50

要有效地实现它,这并不是件简单的事情。此外,这是没有任何意义的,除非你正在学习这门学科。条件变量在这里不是一个很好的选择,因为它不能很好地扩展。

我建议您看看成熟的运行时库如何实现叉-连接并行,并向它们学习或在应用程序中使用它们。参见http://www.openmprtl.org/http://opentbb.org/https://www.cilkplus.org/ --所有这些都是开源的.

OpenMP是您所要寻找的最接近的模型,它具有最有效的叉-连接障碍实现。尽管如此,由于它是专为高性能计算机设计的,而且缺乏动态可组合性,因此也有其缺点。TBB和Cilk在模块和库中的嵌套并行性和使用效果最好,可以在外部并行区域的上下文中使用。

票数 2
EN

Stack Overflow用户

发布于 2016-08-24 06:41:34

您可以使用屏障或条件变量启动所有线程。然后,当所有线程结束其工作时(通过对所有线程的联接方法,线程是阻塞的),线程就可以等待,然后在一个循环中打印它们的数据。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39115581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档