How I can run two threads parallelly one by one? - c++

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

Related

Condition variable custom wait function

I created custom SpinLock class
I want to use this class in condition variable, but have an error
error: no matching function for call to ‘std::condition_variable::wait(std::unique_lock<Spinlock>&)’
cv_.wait(lk);
I have error in line cv_.wait(lk);
How can I support my SpinLock for condition variable?
I want to declare my own function wait void wait(unique_lock<SpinLock>& __lock, _Predicate __p) signature.
#include <atomic>
#include <iostream>
#include <string>
#include <cstdlib> // atoi
#include <thread> // thread
#include <mutex> // mutex
#include <condition_variable>
#include <vector>
using namespace std;
class Spinlock {
private:
std::atomic_flag lock_ = ATOMIC_FLAG_INIT;
public:
void lock()
{
while (lock_.test_and_set(std::memory_order_acquire)) continue;
}
void unlock()
{
lock_.clear(std::memory_order_release);
}
};
class PrintOrder final {
public:
PrintOrder(int n, int threadNum)
: maxNum_(n)
, curNum_(0)
{
startTime_ = chrono::steady_clock::now();
threads_.reserve(threadNum);
unique_lock<Spinlock> lk(spinLock_);
for(int x = 0; x < threadNum; ++x)
{
threads_.emplace_back(&PrintOrder::background, this, x);
}
}
~PrintOrder() {
for(auto&& th : threads_)
{
th.join();
}
auto endTime = chrono::steady_clock::now();
auto diff = endTime - startTime_;
cout << chrono::duration <double, milli> (diff).count() << " ms" << endl;
}
void background(int x) {
while(true) {
unique_lock<Spinlock> lk(spinLock_);
// wait until it's this thread's turn or curNum_ > maxNum_
while((curNum_ % threads_.size()) != x and curNum_ <= maxNum_)
{
cv_.wait(lk);
}
if(curNum_ > maxNum_)
{
break;
}
cout << curNum_ << endl;
++curNum_;
cv_.notify_all();
}
}
private:
int maxNum_;
int curNum_;
Spinlock spinLock_;
condition_variable cv_;
vector<thread> threads_;
chrono::time_point<chrono::steady_clock> startTime_;
};
int main(int argc, char **argv) {
if (argc == 3)
{
int maxNum = atoi(argv[1]);
int threadsNum = atoi(argv[2]);
PrintOrder printOrder(maxNum, threadsNum);
} else {
cout << "ERROR: expected console input: <maxNum> <threadsNum>" << endl;
}
return 0;
}
std::condition_variable only supports std::unique_lock<std::mutex>. Use std::condition_variable_any instead.
The condition_variable_any class is a generalization of std::condition_variable. Whereas std::condition_variable works only on std::unique_lock<std::mutex>, condition_variable_any can operate on any lock that meets the BasicLockable requirements.

Thread safe ExpiringDeque data structure in C++

I am trying to create a data structure, ExpiringDeque. It should be somewhat similar to std::deque. Let's say I need only push_back(), size() and pop_front(). The data structure needs to automatically expire up to N first elements every T seconds.
This data structure needs to manage its own queue and expiration thread internally.
How do I write it in a thread safe way? This is an example that I came up with, does this seem reasonable? What am I missing?
#include <algorithm>
#include <atomic>
#include <cassert>
#include <deque>
#include <mutex>
#include <thread>
#include <unistd.h>
#include <iostream>
template <typename T>
class ExpiringDeque {
public:
ExpiringDeque(int n, int t) : numElements_(n), interval_(t), running_(true), items_({}) {
expiringThread_ = std::thread{[&] () {
using namespace std::chrono_literals;
int waitCounter = 0;
while (true) {
if (!running_) {
return;
}
std::this_thread::sleep_for(1s);
if (waitCounter++ < interval_) {
continue;
}
std::lock_guard<std::mutex> guard(mutex_);
waitCounter = 0;
int numToErase = std::min(numElements_, static_cast<int>(items_.size()));
std::cout << "Erasing " << numToErase << " elements\n";
items_.erase(items_.begin(), items_.begin() + numToErase);
}
}};
}
~ExpiringDeque() {
running_ = false;
expiringThread_.join();
}
T pop_front() {
if (items_.size() == 0) {
throw std::out_of_range("Empty deque");
}
std::lock_guard<std::mutex> guard(mutex_);
T item = items_.front();
items_.pop_front();
return item;
}
int size() {
std::lock_guard<std::mutex> guard(mutex_);
return items_.size();
}
void push_back(T item) {
std::lock_guard<std::mutex> guard(mutex_);
items_.push_back(item);
}
private:
int numElements_;
int interval_;
std::atomic<bool> running_;
std::thread expiringThread_;
std::mutex mutex_;
std::deque<T> items_;
};
int main() {
ExpiringDeque<int> ed(10, 3);
ed.push_back(1);
ed.push_back(2);
ed.push_back(3);
assert(ed.size() == 3);
assert(ed.pop_front() == 1);
assert(ed.size() == 2);
// wait for expiration
sleep(5);
assert(ed.size() == 0);
ed.push_back(10);
assert(ed.size() == 1);
assert(ed.pop_front() == 10);
return 0;
}
You can avoid an unnecessary wait in the destructor of ExpiringDeque by using a condition variable. I would also use std::condition_variable::wait_for with a predicate to check the running_ flag. This will ensure that you either wait for a timeout or a notification, whichever is earlier. You avoid using waitCounter and continue this way.
Another thing you should do is lock the mutex before checking the size of your deque in pop_front(), otherwise it's not thread safe.
Here's an updated version of your code:
template <typename T>
class ExpiringDeque {
public:
ExpiringDeque(int n, int t) : numElements_(n), interval_(t), running_(true), items_({}), cv_() {
expiringThread_ = std::thread{ [&]() {
using namespace std::chrono_literals;
while (true) {
//Wait for timeout or notification
std::unique_lock<std::mutex> lk(mutex_);
cv_.wait_for(lk, interval_ * 1s, [&] { return !running_; });
if (!running_)
return;
//Mutex is locked already - no need to lock again
int numToErase = std::min(numElements_, static_cast<int>(items_.size()));
std::cout << "Erasing " << numToErase << " elements\n";
items_.erase(items_.begin(), items_.begin() + numToErase);
}
} };
}
~ExpiringDeque() {
//Set flag and notify worker thread
{
std::lock_guard<std::mutex> lk(mutex_);
running_ = false;
}
cv_.notify_one();
expiringThread_.join();
}
T pop_front() {
std::lock_guard<std::mutex> guard(mutex_);
if (items_.size() == 0) {
throw std::out_of_range("Empty deque");
}
T item = items_.front();
items_.pop_front();
return item;
}
...
private:
int numElements_;
int interval_;
bool running_;
std::thread expiringThread_;
std::mutex mutex_;
std::deque<T> items_;
std::condition_variable cv_;
};
You can make the running_ flag a normal bool since the std::condition_variable::wait_for atomically checks for the timeout or notification.

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

Sync queue between two threads

This is a simple program which has a function start() which waits for user to enter something(using infinite loop) and stores it in queue. start() runs in a separate thread. After user enters some value, the size of queue remains zero in main. How can the queue be synchronized?
code: source.cpp
#include <iostream>
#include "kl.h"
using namespace std;
int main()
{
std::thread t1(start);
while (1)
{
if (q.size() > 0)
{
std::cout << "never gets inside this if\n";
std::string first = q.front();
q.pop();
}
}
t1.join();
}
code: kl.h
#include <queue>
#include <iostream>
#include <string>
void start();
static std::queue<std::string> q;
code: kl.cpp
#include "kl.h"
using namespace std;
void start()
{
char i;
string str;
while (1)
{
for (i = 0; i <= 1000; i++)
{
//other stuff and str input
q.push(str);
}
}
}
Your code contains a race - by me it crashed; both threads are potentially modifying a shared queue. (Also, you're looping with char i for values up to 1000 - not a good idea, probably.)
You should protect your shared queue with a std::mutex, and use a std::condition_variable to notify that there is a reason to check the queue.
Specifically, you should consider the following (which is very common for your case of a producer consumer):
Access the queue only when holding the mutex.
Use the condition variable to notify that you've pushed something into it.
Use the condition variable to specify a condition on when there's a point to continue processing.
Here is a rewrite of your code:
#include <iostream>
#include <queue>
#include <thread>
#include <condition_variable>
#include <mutex>
using namespace std;
std::queue<std::string> q;
std::mutex m;
std::condition_variable cv;
void start()
{
string str;
for (std::size_t i = 0; i <= 1000; i++) {
//other stuff and str input
std::cout << "here" << std::endl;
std::unique_lock<std::mutex> lk(m);
q.push(str);
lk.unlock();
cv.notify_one();
}
}
int main()
{
std::thread t1(start);
for (std::size_t i = 0; i <= 1000; i++)
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return !q.empty();});
std::string first = q.front();
q.pop();
}
t1.join();
}
My synced queue class example and its usage:
template<typename T>
class SyncQueue
{
std::queue<T> m_Que;
std::mutex m_Lock;
std::condition_variable m_ConVar;
public:
void enque(T item)
{
std::unique_lock<std::mutex> lock(m_Lock);
m_Que.push(item);
lock.unlock();
m_ConVar.notify_all();
}
T deque()
{
std::unique_lock<std::mutex> lock(m_Lock);
do
{
m_ConVar.wait(lock);
} while(m_Que.size() == 0); // extra check from spontaneous notifications
auto ret = m_Que.front();
m_Que.pop();
return ret;
}
};
int main()
{
using namespace std::chrono_literals;
SyncQueue<int> sq;
std::thread consumer([&sq]()
{
std::cout << "consumer" << std::endl;
for(;;)
{
std::cout << sq.deque() << std::endl;
}
});
std::thread provider([&sq]()
{
std::this_thread::sleep_for(1s);
sq.enque(1);
std::this_thread::sleep_for(3s);
sq.enque(2);
std::this_thread::sleep_for(5s);
sq.enque(3);
});
consumer.join();
return 0;
}
/* Here I have a code snippate with Separate class for
Producing and Consuming along with buffer class */
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <deque>
#include <vector>
using namespace std;
mutex _mutex_1,_mutex_2;
condition_variable cv;
template <typename T>
class Queue
{
deque<T> _buffer;
const unsigned int max_size = 10;
public:
Queue() = default;
void push(const T& item)
{
while(1)
{
unique_lock<mutex> locker(_mutex_1);
cv.wait(locker,[this](){ return _buffer.size() < max_size; });
_buffer.push_back(item);
locker.unlock();
cv.notify_all();
return;
}
}
T pop()
{
while(1)
{
unique_lock<mutex> locker(_mutex_1);
cv.wait(locker,[this](){ return _buffer.size() > 0; });
int back = _buffer.back();
_buffer.pop_back();
locker.unlock();
cv.notify_all();
return back;
}
}
};
class Producer
{
Queue<int>* _buffer;
public:
Producer(Queue<int>* _buf)
{
this->_buffer = _buf;
}
void run()
{
while(1)
{
auto num = rand()%100;
_buffer->push(num);
_mutex_2.lock();
cout<<"Produced:"<<num<<endl;
this_thread::sleep_for(std::chrono::milliseconds(50));
_mutex_2.unlock();
}
}
};
class Consumer
{
Queue<int>* _buffer;
public:
Consumer(Queue<int>* _buf)
{
this->_buffer = _buf;
}
void run()
{
while(1)
{
auto num = _buffer->pop();
_mutex_2.lock();
cout<<"Consumed:"<<num<<endl;
this_thread::sleep_for(chrono::milliseconds(50));
_mutex_2.unlock();
}
}
};
void client()
{
Queue<int> b;
Producer p(&b);
Consumer c(&b);
thread producer_thread(&Producer::run, &p);
thread consumer_thread(&Consumer::run, &c);
producer_thread.join();
consumer_thread.join();
}
int main()
{
client();
return 0;
}

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

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