6

我必须处理以下场景:我有 5 个任务(“A”、“B”、“C”、“D”、“E”),我想将它们并行化,但考虑到它们的依赖关系。它们必须按这样的顺序执行:

A --> B --\
C ----------> E
D --------/

因此,当所有先前的都完成时执行“E”,并且必须在 A 之后执行“B”。这是我的问题。是否有任何现成的解决方案(STL、Boost)?或者我将不得不基于 std::thread 来实现它?

4

3 回答 3

11

查看TBB 的流程图PPL

TBB 链接中的示例大致显示了您所绘制的内容。您已经将问题抽象为任务。一开始不需要深入到线程级别。

于 2013-06-17T07:23:45.333 回答
2

我认为您可以使用 OpenMPsection指令执行此操作,您可以使用 ICC、GCC 和 MSVC 执行此操作。OpenMPtask指令可能是更好的选择,可以使用 ICC 和 GCC,但不能使用任何版本的 MSVC。

下面的代码使用 OpenMP sections。由于 E 在所有其他任务完成后运行,因此也可以并行化它,因此在以下代码E中,所有线程在A, B, C, D完成后运行。如果E在循环上进行迭代,那么您可以通过这种方式并行化循环。我不确定这是否是您想要的,但很容易让它像您想要的那样在一个线程中运行。

#include <stdio.h>
#include <omp.h>

void A() { printf("A\n"); }
void B() { printf("B\n"); }
void C() { printf("C\n"); }
void D() { printf("D\n"); }
void E() {
  printf("E: %d\n", omp_get_thread_num());
  #pragma omp for
  for(int i=0; i<10; i++) {
     //do something as a function of i
  }
}

void foo() {
#pragma omp parallel // starts a new team
 {  
   #pragma omp sections // divides the team into sections
   { 
     { A();  B(); }
     #pragma omp section
     { C(); }
     #pragma omp section
     { D(); }
   }
   E();
 }
}

int main() {
    foo();
}   
于 2013-06-17T08:30:58.447 回答
1

您可以使用我从未使用过但看起来非常简单的 std::thread。

这是在 cppreference.com 上找到的一个简单程序的示例:

#include <iostream>
#include <thread>
#include <chrono>

void foo()
{
    // simulate expensive operation
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

void bar()
{
    // simulate expensive operation
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

int main()
{
    std::cout << "starting first helper...\n";
    std::thread helper1(foo);

    std::cout << "starting second helper...\n";
    std::thread helper2(bar);

    std::cout << "waiting for helpers to finish...\n";
    helper1.join();
    helper2.join();

    std::cout << "done!\n";
}

您可以使用 join() 函数等待线程完成。例如,您创建一个将执行任务 A 的新线程。然后等待它完成,然后再创建一个将执行任务 B 的新线程。

您应该使用 g++ -std=c++0x -pthread main.cpp 进行编译

或者,您可以搜索 MPI 和 OpenMP,它们可以提供 std::thread 无法提供的一些可能性。

于 2013-06-17T07:15:10.940 回答