Dejwi
Dejwi

Reputation: 4487

C++ chain of tasks

I have to handle the following scenerio: I've 5 tasks("A","B","C","D","E"), I'd like to parallelize them but in respect to their dependiences. They have to be executed in such an order:

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

So "E" is executed when all the previous ones are finished and "B" has to be executed after A. And here is my question. Are there any ready to go solutions (STL, Boost)? Or I will have to implement it basing on std::thread?

Upvotes: 7

Views: 1921

Answers (3)

user2088790
user2088790

Reputation:

I think you can do this with the OpenMP section directive which you can do with ICC, GCC, and MSVC. The OpenMP task directive is probably a better choice and can be done with ICC and GCC but not with any version of MSVC.

The code below uses OpenMP sections. Since E is run after all other tasks are finished it's possible to parallelize it as well so in the following code E is run by all threads after A, B, C, D have finished. If E is iterating over a loop then you can parallelize the loop this way. I'm not sure that's what you want but it's easy to make it run in one thread as if you wanted.

#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();
}   

Upvotes: 2

Dmitry Ledentsov
Dmitry Ledentsov

Reputation: 3660

check out TBB's Flow Graph or the PPL.

The example in the TBB link shows approximately what you have sketched. You already formulated your problem abstracted as tasks. No need to get down to the thread level at first.

Upvotes: 12

Silouane Gerin
Silouane Gerin

Reputation: 1251

You can use std::thread which I never used but seems pretty straightforward.

Here's an example of a simple program found on 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";
}

You can use the join() function to wait for a thread to finish. For example you create a new thread that will execute the task A. Then you wait for it to finish before creating a new thread that will execute task B.

You should compile with g++ -std=c++0x -pthread main.cpp

Alternatively you can search for MPI and OpenMP that can provide some possibilities std::thread can't.

Upvotes: 1

Related Questions