Having several threads running I need to guaranty that every of my threads reached a certain point before proceeding. I need to implement a kind of barrier. Consider a function func
which can be run from several threads:
void func()
{
operation1();
// wait till all threads reached this point
operation2();
}
What is best way to realise this barrier using C++ 11 and VS12, considering boost if needed.
A synchronization barrier enables multiple threads to wait until all threads have all reached a particular point of execution before any thread continues. Synchronization barriers cannot be shared across processes.
You could use boost::barrier
Unfortunately, the thread barrier concept itself is not part of c++11 or visual c++.
In pure c++11 you could use a condition variable and a counter.
#include <iostream>
#include <condition_variable>
#include <thread>
#include <chrono>
class my_barrier
{
public:
my_barrier(int count)
: thread_count(count)
, counter(0)
, waiting(0)
{}
void wait()
{
//fence mechanism
std::unique_lock<std::mutex> lk(m);
++counter;
++waiting;
cv.wait(lk, [&]{return counter >= thread_count;});
cv.notify_one();
--waiting;
if(waiting == 0)
{
//reset barrier
counter = 0;
}
lk.unlock();
}
private:
std::mutex m;
std::condition_variable cv;
int counter;
int waiting;
int thread_count;
};
int thread_waiting = 3;
my_barrier barrier(3);
void func1()
{
std::this_thread::sleep_for(std::chrono::seconds(3));
barrier.wait();
std::cout << "I have awakened" << std::endl;
}
void func2()
{
barrier.wait();
std::cout << "He has awakened!!" << std::endl;
}
int main() {
std::thread t1(func1);
std::thread t2(func2);
std::thread t3(func2);
t1.join();
t2.join();
t3.join();
}
Each thread wait till a predicate is met. The last thread will make the predicate valid, and allow the waiting threads to proceed. If you want to reuse the barrier (for instance call the function multiple times), you need another variable to reset the counter.
This current implementation is limited. A calling func();func();
twice may not make threads wait the second time.
An option could be the use of OpenMP framework.
#include <omp.h>
void func()
{
#pragma omp parallel num_threads(number_of_threads)
{
operation1();
#pragma omp barrier
// wait till all threads reached this point
operation2();
}
}
Compile the code with -fopenmp
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With