What is the best way to realize a synchronization barrier between threads - c++

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.

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

Solution:
#include <cassert>
#include <condition_variable>
class Barrier
{
public:
Barrier(std::size_t nb_threads)
: m_mutex(),
m_condition(),
m_nb_threads(nb_threads)
{
assert(0u != m_nb_threads);
}
Barrier(const Barrier& barrier) = delete;
Barrier(Barrier&& barrier) = delete;
~Barrier() noexcept
{
assert(0u == m_nb_threads);
}
Barrier& operator=(const Barrier& barrier) = delete;
Barrier& operator=(Barrier&& barrier) = delete;
void Wait()
{
std::unique_lock< std::mutex > lock(m_mutex);
assert(0u != m_nb_threads);
if (0u == --m_nb_threads)
{
m_condition.notify_all();
}
else
{
m_condition.wait(lock, [this]() { return 0u == m_nb_threads; });
}
}
private:
std::mutex m_mutex;
std::condition_variable m_condition;
std::size_t m_nb_threads;
};
Example:
#include <chrono>
#include <iostream>
#include <thread>
Barrier barrier(2u);
void func1()
{
std::this_thread::sleep_for(std::chrono::seconds(3));
barrier.Wait();
std::cout << "t1 awakened" << std::endl;
}
void func2()
{
barrier.Wait();
std::cout << "t2 awakened" << std::endl;
}
int main()
{
std::thread t1(func1);
std::thread t2(func2);
t1.join();
t2.join();
return 0;
}
Try It Online: WandBox

Related

Thread Pool join hangs when oversubscribing threads

I'm having an issue with a thread hanging when joining my threads in a thread pool I have created. The issue only occurs if I loop over the thread pool execution a large number of times.
I have a thread pool class like the following;
#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <atomic>
#include <vector>
#include <thread>
#include <iostream>
class ThreadPool
{
public:
ThreadPool()
{
m_shutdown.store(false, std::memory_order_relaxed);
createThreads(1);
}
ThreadPool(std::size_t numThreads)
{
m_shutdown.store(false, std::memory_order_relaxed);
createThreads(numThreads);
}
void add_job(std::function<void()> new_job)
{
{
std::scoped_lock<std::mutex> lock(m_jobMutex);
m_jobQueue.push(new_job);
}
m_notifier.notify_one();
}
void waitFinished()
{
{
std::unique_lock<std::mutex> lock(m_jobMutex);
m_finished.wait(lock, [this] {return m_jobQueue.empty(); }); //&& busy == 0
}
m_shutdown.store(true, std::memory_order_relaxed);
m_notifier.notify_all();
for (std::thread& th : m_threads)
{
th.join();
}
m_threads.clear();
}
private:
using Job = std::function<void()>;
std::vector<std::thread> m_threads;
std::queue<Job> m_jobQueue;
std::condition_variable m_notifier;
std::condition_variable m_finished;
std::mutex m_jobMutex;
std::atomic<bool> m_shutdown;
void createThreads(std::size_t numThreads)
{
// Settup threads
m_threads.reserve(numThreads);
for (int i = 0; i != numThreads; ++i)
{
m_threads.emplace_back(std::thread([this]()
{
// Infinite loop to consume tasks from queue and execute
while (true)
{
Job job;
{
std::unique_lock<std::mutex> lock(m_jobMutex);
m_notifier.wait(lock, [this] {return !m_jobQueue.empty() || m_shutdown.load(std::memory_order_relaxed); });
if (m_shutdown.load(std::memory_order_relaxed) || m_jobQueue.empty())
{
break;
}
job = std::move(m_jobQueue.front());
m_jobQueue.pop();
}
job();
m_finished.notify_one();
}
}));
}
}
};
I run this in a simple manner, like the following;
void threader (int x) {
std::cout<<"In threaded function: "<<x<<std::endl;
}
int main()
{
//outer loop
for (auto i = 0; i < 10000; i++) {
//Thread pool
int num_threads = std::thread::hardware_concurrency();
ThreadPool test_pool(num_threads);
// Assign work
for (int j = 0; j < 48; j++) {
test_pool.add_job(std::bind(threader, j));
}
test_pool.waitFinished();
std::cout<<"Thread Pool Done"<<std::endl;
}
}
After a number of outer loop iterations the join in the waitFinished hangs for a thread. The error only seems to occur after a number of iterations of the outer loop large enough. I have investigated this and can see that the threader function get's called 48 times, so looks like all threads complete. It seems to be the joining of threads in the waitFinished function of the ThreadPool that is causing the hang.
Is there something obvious I'm doing wrong ?
Many thanks!

How I can run two threads parallelly one by one?

In C++ how i can write two parallel threads which will work one by one.For example in below code it need to print 0 t 100 sequentially.In below code the numbers are printing ,but all are not sequential.I need to print like 1,2,3,4,5,6.....99.If any body know , try to add with sample code also.
#pragma once
#include <mutex>
#include <iostream>
#include <vector>
#include <thread>
#include <condition_variable>
using namespace std;
class CuncurrentThread
{
public:
mutex mtx;
condition_variable cv;
static bool ready;
static bool processed;
void procThread1()
{
for (int i = 0; i < 100; i += 2)
{
unique_lock<mutex> lk(mtx);
cv.notify_one();
if(lk.owns_lock())
cv.wait(lk);
cout << "procThread1 : " << i << "\n";
lk.unlock();
cv.notify_one();
}
};
void procThread2()
{
for (int i = 1; i < 100; i += 2)
{
unique_lock<mutex> lk(mtx);
cv.notify_one();
if (lk.owns_lock())
cv.wait(lk);
cout << "procThread2 : " << i << "\n";
lk.unlock();
cv.notify_one();
}
};
static void ThreadDriver(CuncurrentThread* thr)
{
vector<thread> threads;
threads.push_back(thread(&CuncurrentThread::procThread1, thr));
threads.push_back(thread(&CuncurrentThread::procThread2, thr));
for (auto& thread : threads)
thread.join();
};
};
bool CuncurrentThread::ready = false;
int main()
{
CuncurrentThread tr;
CuncurrentThread::ThreadDriver(&tr);
}
Assuming you have a valid use case for using two threads like this, here is an example. I prefer using std::async over std::thread it has better abstraction and information exchange with the main thread.
The example is written for 2 threads but can easily be changed to more threads.
Live demo here : https://onlinegdb.com/eQex9o_nMz
#include <future>
#include <condition_variable>
#include <iostream>
// Setup a helper class that sets up
// the three things needed to correctly
// use a condition variable
// 1) a mutex
// 2) a variable
// 3) a condition_variable (which is more of a signal then a variable)
//
// also give this class some functions
// so the the code becomes more self-explaining
class thread_switcher_t
{
public:
void thread1_wait_for_turn()
{
std::unique_lock<std::mutex> lock{ m_mtx };
m_cv.wait(lock, [&] {return (thread_number==0); });
}
void thread2_wait_for_turn()
{
std::unique_lock<std::mutex> lock{ m_mtx };
m_cv.wait(lock, [&] {return (thread_number==1); });
}
void next_thread()
{
std::unique_lock<std::mutex> lock{ m_mtx };
thread_number = (thread_number + 1) % 2;
m_cv.notify_all();
}
private:
std::size_t thread_number{ 0 };
std::mutex m_mtx;
std::condition_variable m_cv;
};
int main()
{
thread_switcher_t switcher;
auto future1 = std::async(std::launch::async, [&]
{
for(std::size_t n = 0; n <= 100; n+=2)
{
switcher.thread1_wait_for_turn();
std::cout << "thread 1 : " << n << "\n";
switcher.next_thread();
}
});
auto future2 = std::async(std::launch::async, [&]
{
for (std::size_t n = 1; n <= 100; n += 2)
{
switcher.thread2_wait_for_turn();
std::cout << "thread 2 : " << n << "\n";
switcher.next_thread();
}
});
future1.get();
future2.get();
return 0;
}
You can use ready variable as a condition for condition variable.
#include <mutex>
#include <iostream>
#include <vector>
#include <thread>
#include <condition_variable>
using namespace std;
class CuncurrentThread
{
public:
mutex mtx;
condition_variable cv;
static bool ready;
//static bool processed;
void procThread1()
{
for (int i = 0; i < 100; i += 2)
{
unique_lock<mutex> lk(mtx);
// cv.notify_one();
// if(lk.owns_lock())
// wait until this condition is true i.e. until ready is false
cv.wait(lk, [&]() { return !ready; });
cout << "procThread1 : " << i << "\n";
// set ready to true and notify waiting thread
ready = true;
lk.unlock();
cv.notify_one();
}
};
void procThread2()
{
for (int i = 1; i < 100; i += 2)
{
unique_lock<mutex> lk(mtx);
// cv.notify_one();
// if (lk.owns_lock())
// wait until this condition is true i.e. until ready is true
cv.wait(lk, [&]() { return ready; });
cout << "procThread2 : " << i << "\n";
// set ready to false and notify waiting thread
ready = false;
lk.unlock();
cv.notify_one();
}
};
static void ThreadDriver(CuncurrentThread* thr)
{
vector<thread> threads;
threads.push_back(thread(&CuncurrentThread::procThread1, thr));
threads.push_back(thread(&CuncurrentThread::procThread2, thr));
for (auto& thread : threads)
thread.join();
};
};
bool CuncurrentThread::ready = false;
int main()
{
CuncurrentThread tr;
CuncurrentThread::ThreadDriver(&tr);
}
Link where I tested this: https://godbolt.org/z/4jEns16oq

C++ sleep for undetermined amount of time

In my code I want my system to sleep, until a condition has been met. An after having searched i have found #include <unistd.h>, but to me it just looks like it sleeps until the time frame has been met. I was wondering if there was a easy way to make the program wait until the condition has been reached.
Here you have a sample of the code to clarify my point
bool check() {
while (condition) {
sleep.here();
} else {
run.the.rest();
}
}
Based on your incomplete pseudo-code and description, here is a class contidion_t, where you can set your condition via set_condition, and a thread blocking in loop will wake up, every time you set it.
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
struct condition_t {
public:
template <typename T>
void loop(T the_rest) {
while(running) {
std::unique_lock<std::mutex> lock_guard(m);
cv.wait(lock_guard, [this] { return ready.load(); });
the_rest();
ready = false;
}
}
void set_condition(bool value) {
ready = value;
if (value) {
cv.notify_one();
}
}
void stop_running() {
running = false;
ready = true;
cv.notify_all();
}
~condition_t () {stop_running();}
private:
std::mutex m;
std::condition_variable cv;
std::atomic<bool> ready{false};
std::atomic<bool> running{true};
};
int main() {
condition_t condition;
std::thread thread(&condition_t::loop<void (void)>, &condition, [] () {
std::cout << "Doing the rest" << std::endl;
});
std::cout << "Thread created but waits\nInput something for continue:";
int something;
std::cin >> something;
std::cout << "Continueing\n";
condition.set_condition(true);
std::cout << "Input something to stop running:";
std::cin >> something;
condition.stop_running();
thread.join();
}

Exercise of multithreading

I have this exercise of multithreading to solve. I have to create a class where 5 threads that wait each other and when the fifth arrives they are all unlocked.
I would like to use mutex and condition variable but I don't know if I'm using them well.
I create a class with the method add() that increment a variableX by 1, creates a thread that receives the function print() and later join() it. The function print() check if the variableX is minor of five, if it's like that the condition variable wait, else the condition variable wake up all the thread with the notify_all() function. The compiler gives 0 error, but with a debug I see that the program gets in a deadlock. Here is a snippet
#include "stdafx.h"
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
void print(mutex & mtx, condition_variable & convar, int x) {
if (x < 5){
unique_lock<mutex> lock(mtx); //acquire and lock the mutex
convar.wait(lock); //unlock mutex and wait
}
else {
convar.notify_all();
cout << "asdasd" << endl;
}
}
class foo {
public:
void add() {
this->x = x + 1;
thread t1(print, ref(mtx), ref(cv), x);
t1.join();
}
private:
mutex mtx;
condition_variable cv;
int x;
};
int main() {
foo f;
f.add();
f.add();
f.add();
f.add();
f.add();
}
Your function
void add() {
this->x = x + 1;
thread t1(print, ref(mtx), ref(cv), x);
t1.join();
}
creates a single thread and then waits (join()) till the thread ends. Since your thread function
void print(mutex & mtx, condition_variable & convar, int x) {
if (x < 5){
unique_lock<mutex> lock(mtx);
convar.wait(lock); // waits if x < 5
}
// ...
and x is presumable (you did fail to initialize it) < 5 you have your deadlock.
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <condition_variable>
using namespace std;
void print(mutex & mtx, condition_variable & convar, int x)
{
if (x < 5) {
unique_lock<mutex> lock{ mtx };
convar.wait(lock);
} else {
convar.notify_all();
cout << "asdasd\n";
}
}
class foo {
private:
mutex mtx;
condition_variable cv;
int x{ 0 };
std::vector<thread> threads;
public:
void add() {
++x;
threads.push_back(thread(print, ref(mtx), ref(cv), x));
}
~foo() {
for (auto &t : threads)
t.join();
}
};
int main() {
foo f;
f.add();
f.add();
f.add();
f.add();
f.add();
}

std::lock_guard won't unlock

I'm trying to lock my list of mutexes in the following code so that only one thread can search it, unlock, lock or modify it at a time.
#include <mutex>
#include <map>
#include <memory>
#include <vector>
#include <thread>
#include <atomic>
#include <iostream>
#include <Windows.h>
struct MoveableMutex
{
std::mutex m;
MoveableMutex() {}
MoveableMutex(MoveableMutex const&) {}
MoveableMutex& operator = (MoveableMutex const&) { return *this; }
};
class Locks
{
private:
static std::mutex map_lock;
static std::uint32_t lock_count;
std::map<std::uint32_t, MoveableMutex> locklist;
public:
std::uint32_t AddLock();
void RemoveLock(std::uint32_t ID);
void Lock(std::uint32_t ID);
bool TryLock(std::uint32_t ID);
void Unlock(std::uint32_t ID);
};
std::uint32_t Locks::lock_count = 0;
std::mutex Locks::map_lock;
std::uint32_t Locks::AddLock()
{
std::lock_guard<std::mutex> guard(map_lock);
locklist.insert(std::make_pair(++lock_count, MoveableMutex()));
return lock_count;
}
void Locks::RemoveLock(std::uint32_t ID)
{
std::lock_guard<std::mutex> guard(map_lock);
auto it = locklist.find(ID);
if (it != locklist.end())
{
it->second.m.unlock();
locklist.erase(it);
}
}
void Locks::Lock(std::uint32_t ID)
{
std::lock_guard<std::mutex> guard(map_lock);
auto it = this->locklist.find(ID);
if (it != this->locklist.end())
{
it->second.m.lock();
}
}
bool Locks::TryLock(std::uint32_t ID)
{
std::lock_guard<std::mutex> guard(map_lock);
auto it = this->locklist.find(ID);
if (it != this->locklist.end())
{
return it->second.m.try_lock();
}
return false;
}
void Locks::Unlock(std::uint32_t ID)
{
std::lock_guard<std::mutex> guard(map_lock);
auto it = this->locklist.find(ID);
if (it != locklist.end())
{
it->second.m.unlock();
}
}
int main()
{
Locks locklist;
int i = locklist.AddLock();
std::atomic<bool> stop(false);
std::atomic<bool> stop2(false);
std::thread o([&]
{
locklist.Lock(i);
while(!stop)
{
std::cout << "Hey\n";
Sleep(100);
}
locklist.Unlock(i);
});
std::thread t([&]
{
locklist.Lock(i);
while(!stop2)
{
std::cout << "Hey2\n";
Sleep(100);
}
locklist.Unlock(i);
});
Sleep(1000);
stop = true;
system("CLS");
o.join();
Sleep(1000);
stop2 = true;
t.join();
return 0;
}
However, with the std::lock_guard inside the Unlock function, it causes a deadlock. If I remove the lock_guard from the Unlock function, it works fine.
Is there a reason the lock_guard isn't destructing or unlocking?
One thread calls Lock, which ends up locking the mutex in the map. The other thread calls Lock, which locks map_lock then tries to lock the mutex in the map, and gets stuck there (with map_lock still held). Eventually, the first thread gets out of the loop and calls Unlock, which gets stuck waiting on map_lock.
The main design flaw here is that you have a thread acquire two locks, one after another. This only works safely if all threads acquire them in the same order (and release in reverse order of acquiring). But your code acquires them in different order at different times: that's a recipe for a deadlock.
See also: lock hierarchy