So I have two threads where they share the same variable, 'counter'. I want to synchronize my threads by only continuing execution once both threads have reached that point. Unfortunately I enter a deadlock state as my thread isn't changing it's checking variable. The way I have it is:
volatile int counter = 0;
Thread() {
- some calculations -
counter++;
while(counter != 2) {
std::this_thread::yield();
}
counter = 0;
- rest of the calculations -
}
The idea is that since I have 2 threads, once they reach that point - at different times - they will increment the counter. If the counter isn't equal to 2, then the thread that reached there first will have to wait until the other has incremented the counter so that they are synced up. Does anyone know where the issue lies here?
To add more information about the problem, I have two threads which perform half of the operations on an array. Once they are done, I want to make sure that they both have completed finish their calculations. Once they are, I can signal the printer thread to wake up and perform it's operation of printing and clearing the array. If I do this before both threads have completed, there will be issues.
Pseudo code:
Thread() {
getLock()
1/2 of the calculations on array
releaseLock()
wait for both to finish - this is the issue
wake up printer thread
}
In situations like this, you must use an atomic counter.
std::atomic_uint counter = 0;
In the given example, there is also no sign that counter got initialized.
You are probably looking for std::conditional_variable: A conditional variable allows one thread to signal to another thread. Because it doesn't look like you are using the counter, and you're only using it for synchronisation, here is some code from another answer (disclaimer: it's one of my answers) that shows std::conditional_variable processing logic on different threads, and performing synchronisation around a value:
unsigned int accountAmount;
std::mutex mx;
std::condition_variable cv;
void depositMoney()
{
// go to the bank etc...
// wait in line...
{
std::unique_lock<std::mutex> lock(mx);
std::cout << "Depositing money" << std::endl;
accountAmount += 5000;
}
// Notify others we're finished
cv.notify_all();
}
void withdrawMoney()
{
std::unique_lock<std::mutex> lock(mx);
// Wait until we know the money is there
cv.wait(lock);
std::cout << "Withdrawing money" << std::endl;
accountAmount -= 2000;
}
int main()
{
accountAmount = 0;
// Run both threads simultaneously:
std::thread deposit(&depositMoney);
std::thread withdraw(&withdrawMoney);
// Wait for both threads to finish
deposit.join();
withdraw.join();
std::cout << "All transactions processed. Final amount: " << accountAmount << std::endl;
return 0;
}
I would look into using a countdown latch. The idea is to have one or more threads block until the desired operation is completed. In this case you want to wait until both threads are finished modifying the array.
Here is a simple example:
#include <condition_variable>
#include <mutex>
#include <thread>
class countdown_latch
{
public:
countdown_latch(int count)
: count_(count)
{
}
void wait()
{
std::unique_lock<std::mutex> lock(mutex_);
while (count_ > 0)
condition_variable_.wait(lock);
}
void countdown()
{
std::lock_guard<std::mutex> lock(mutex_);
--count_;
if (count_ == 0)
condition_variable_.notify_all();
}
private:
int count_;
std::mutex mutex_;
std::condition_variable condition_variable_;
};
and usage would look like this
std::atomic<int> result = 0;
countdown_latch latch(2);
void perform_work()
{
++result;
latch.countdown();
}
int main()
{
std::thread t1(perform_work);
std::thread t2(perform_work);
latch.wait();
std::cout << "result = " << result;
t1.join();
t2.join();
}
Related
I have a ring buffer that is used for read/writers. I keep track of the number if entries in the ring buffer and do not allow overwriting entries that have not been read. I use std::condition_variable wait() and notify_one() to synchronize the readers and writers. Basically the condition on the reader is that the number of entries > 0. The condition on the writers is that the number of entries < capacity.
It all seems to work but there is one thing I don't understand. When a reader or writer calls notify_one(), it does not cause a context switch. I've read and understand that it works this way. However, in a case where a writer writes an entry to fill the buffer, the writer calls notify_one() and continues to write another in which case its predicate fails in its wait(). In this case I see that another writer() may wake up and its predicate will fail as well. Then a reader will wake up and its predicate succeeds and it can begin reading.
What I don't understand it why on one notify_one() multiple threads are being unblocked. Does a wait() with a failed predicate not eat up the notify? I can't find anything that states this is the case.
I could call notify_all() just to be sure but it seems to be working with notify_one().
Here's the code.
#include <iostream>
#include <stdint.h>
#include <boost/circular_buffer.hpp>
#include <condition_variable>
#include <thread>
// ring buffer with protection for overwrites
template <typename T>
class ring_buffer {
public:
ring_buffer(size_t size) {
cb.set_capacity(size);
}
void read(T& entry) {
{
std::unique_lock<std::mutex> lk(cv_mutex);
cv.wait(lk, [this] {
std::cout << "read woke up, test=" << (cb.size() > 0) << std::endl;
return 0 < cb.size();});
auto iter = cb.begin();
entry = *iter;
cb.pop_front();
std::cout << "Read notify_one" << std::endl;
}
cv.notify_one();
}
void write(const T& entry) {
{
std::unique_lock<std::mutex> lk(cv_mutex);
//std::cout << "Write wait" << std::endl;
cv.wait(lk, [this] {
std::cout << "write woke up, test=" << (cb.size() < cb.capacity()) << std::endl;
return cb.size() < cb.capacity();});
cb.push_back(entry);
std::cout << "Write notify_one" << std::endl;
}
cv.notify_one();
}
size_t get_number_entries() {
std::unique_lock<std::mutex> lk(cv_mutex);
return cb.size();
}
private:
boost::circular_buffer<T> cb;
std::condition_variable cv;
std::mutex cv_mutex;
};
void write_loop(ring_buffer<int> *buffer) {
for (int i = 0; i < 100000; ++i) {
buffer->write(i);
}
}
void read_loop(ring_buffer<int> *buffer) {
for (int i = 0; i < 50000; ++i) {
int val;
buffer->read(val);
}
}
int main() {
ring_buffer<int> buffer(1000);
std::thread writer(write_loop, &buffer);
std::thread reader(read_loop, &buffer);
std::thread reader2(read_loop, &buffer);
writer.join();
reader.join();
reader2.join();
return 0;
}
I see the following in the output where multiple threads are awoken because the predicate is false.
read woke up, test=0
read woke up, test=0
write woke up, test=1
You are seeing the initial test of the condition when each of your read threads checks if it should wait, or if the condition is already met.
From here, this overload of wait() is equivalent to
while (!pred()) {
wait(lock);
}
So wait() is only called when the condition is true, but the condition must be checked first.
read woke up, test=0 // tests condition on reader1 thread, false, wait is called
read woke up, test=0 // tests condition on reader2 thread, false, wait is called
write woke up, test=1 // tests condition on writer thread, true, wait is not called
This might make it obvious where 2 values are written and each reader will only read a single value.
I'm trying to unit test an atomic library (I am aware that an atomic library is not suitable for unit testing, but I still want to give it a try)
For this, I want to let X parallel threads increment a counter and evaluate the resulting value (it should be X).
The code is below. The problem is that is it never breaks. The Counter always nicely ends up being 2000 (see below). What I also notice is that the cout is also printed as a whole (instead of being mingled, what I remember seeing with other multithreaded couts)
My question is: why doesn't this break? Or how can I let this break?
#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
#include <condition_variable>
std::mutex m;
std::condition_variable cv;
bool start = false;
int Counter = 0;
void Inc() {
// Wait until test says start
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, [] {return start; });
std::cout << "Incrementing in thread " << std::this_thread::get_id() << std::endl;
Counter++;
}
int main()
{
std::vector<std::thread> threads;
for (int i = 0; i < 2000; ++i) {
threads.push_back(std::thread(Inc));
}
// signal the threads to start
{
std::lock_guard<std::mutex> lk(m);
start = true;
}
cv.notify_all();
for (auto& thread : threads) {
thread.join();
}
// Now check whether value is right
std::cout << "Counter: " << Counter << std::endl;
}
The results looks like this (but then 2000 lines)
Incrementing in thread 130960
Incrementing in thread 130948
Incrementing in thread 130944
Incrementing in thread 130932
Incrementing in thread 130928
Incrementing in thread 130916
Incrementing in thread 130912
Incrementing in thread 130900
Incrementing in thread 130896
Counter: 2000
Any help would be appreciated
UPDATE: Reducing the nr of threads to 4, but incrementing a million times in a for loop (as suggested by #tkausl) the cout of thread id appear to be sequential..
UPDATE2: Turns out that the lock had to be unlocked to prevent exclusive access per thread (lk.unlock()). An additional yield in the for-loop increased the race condition effect.
cv.wait(lk, [] {return start; }); only returns with the lk acquired. So it's exclusive. You might want to unlock lk right after:
void Inc() {
// Wait until test says start
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, [] {return start; });
lk.unlock();
Counter++;
}
And you must remove std::cout, because it potentially introduces synchronization.
Considering the following, simple code:
using ms = std::chrono::milliseconds;
int val = 0;
for(;;)
{
std::cout << val++ << ' ';
std::this_thread::sleep_for(ms(200));
}
We see that we infinitely print subsequent numbers each 0.2 second.
Now, I would like to implement the same logic using a helper class and multithreading. My aim is to be able to run something similar to this:
int main()
{
Foo f;
std::thread t1(&Foo::inc, f);
std::thread t2(&Foo::dis, f);
t1.join();
t2.join();
}
where Foo::inc() will increment a member variable val of an object f by 1 and Foo::dis() will display the same variable.
Since the original idea consisted of incrementing and printing the value infinitely, I would assume that both of those functions must contain an infinite loop. The problem that could occur is data race - reading and incrementing the very same variable. To prevent that I decided to use std::mutex.
My idea of implementing Foo is as follows:
class Foo {
int val;
public:
Foo() : val{0} {}
void inc()
{
for(;;){
mtx.lock();
++val;
mtx.unlock();
}
}
void dis()
{
using ms = std::chrono::milliseconds;
for(;;){
mtx.lock();
std::cout << val << ' ';
std::this_thread::sleep_for(ms(200));
mtx.unlock();
}
}
};
Obviously it's missing the mtx object, so the line
std::mutex mtx;
is written just under the #includes, declaring mtx as a global variable.
To my understanding, combining this class' definition with the above main() function should issue two, separate, infinite loops that each will firstly lock the mutex, either increment or display val and unlock the mutex so the other one could perform the second action.
What actually happens is instead of displaying the sequence of 0 1 2 3 4... it simply displays 0 0 0 0 0.... My guess is that I am either using std::mutex::lock and std::mutex::unlock incorrectly, or my fundamental understanding of multithreading is lacking some basic knowledge.
The question is - where is my logic wrong?
How would I approach this problem using a helper class and two std::threads with member functions of the same object?
Is there a guarantee that the incrementation of val and printing of it will each occur one after the other using this kind of logic? i.e. will there never be a situation when val is incremented twice before it being displayed, or vice versa?
You are sleeping with the thread locked preventing the other thread from running for most of the time.
void dis()
{
using ms = std::chrono::milliseconds;
for(;;){
mtx.lock();
std::cout << val << ' ';
std::this_thread::sleep_for(ms(200)); // this is still blocking the other thread
mtx.unlock();
}
}
Try this:
void dis()
{
using ms = std::chrono::milliseconds;
for(;;){
mtx.lock();
std::cout << val << ' ';
mtx.unlock(); // unlock to allow the other thread to progress
std::this_thread::sleep_for(ms(200));
}
}
Also, rather than using a global std::mutex you could add it as a member of your class.
If you want to synchronize the threads to produce an even output of numbers incrementing by exactly one each time then you need something like a std::condition_variable so that each thread can signal the other when it has done it's part of the job (thread one - incrementing and thread 2 - printing).
Here is an example:
class Foo {
int val;
std::mutex mtx;
std::condition_variable cv;
bool new_value; // flag when a new value is ready
public:
Foo() : val{0}, new_value{false} {}
void inc()
{
for(;;){
std::unique_lock<std::mutex> lock(mtx);
// release the lock and wait until new_value has been consumed
cv.wait(lock, [this]{ return !new_value; }); // wait for change in new_value
++val;
new_value = true; // signal for the other thread there is a new value
cv.notify_one(); // wake up the other thread
}
}
void dis()
{
using ms = std::chrono::milliseconds;
for(;;){
// a nice delay
std::this_thread::sleep_for(ms(200));
std::unique_lock<std::mutex> lock(mtx);
// release the lock and wait until new_value has been produced
cv.wait(lock, [this]{ return new_value; }); // wait for a new value
std::cout << val << ' ' << std::flush; // don't forget to flush
new_value = false; // signal for the other thread that the new value was used
cv.notify_one(); // wake up the other thread
}
}
};
int main(int argc, char** argv)
{
Foo f;
std::thread t1(&Foo::inc, &f);
std::thread t2(&Foo::dis, &f);
t1.join();
t2.join();
}
A mutex is not a signal. It is not fair. You can unlock then relock a mutex, and someone waiting for it can never notice.
All it guarantees is that exactly one thread has it locked.
Your task, splitting it into two threads, seems utterly pointless. Using sleep for is also a bad idea, as printing takes an unknown amount of time, making the period between displays drift by an unpredictable amount.
You probably (A) do not want to do this, and failing that (B) use a condition variable. One thread increments the value every X time (based off a fixed start time, not based off delays of X), and then signs the condition variable. It holds no mutex while waiting.
The other thread waits on the condition variable and the counter value changing. When it wakes, it copies the counter, unlocks, prints once, updates the last value seen, then waits on the condition variable (and value changing) again.
A mild benefit to this is that if the io is ridiculously slow or blocking, the counter keeps incrementing, so other consumers can use it.
struct Counting {
int val = -1; // optionally atomic
std::mutex mtx;
std::condition_variable cv;
void counting() {
while(true){
{
auto l=std::unique_lock<std::mutex>(mtx);
++val; // even if atomic, val must be modified while or before the mtx is held and before the notify.
}
// or notify all:
cv.notify_one(); // no need to hold lock here
using namespace std::literals;
std::this_thread::sleep_for(200ms); // ideally wait to an absolute time instead of delay here
}
}
void printing() {
int old_val=-1;
while(true){
int new_val=[&]{
auto lock=std::unique_lock<std::mutex>(mtx);
cv.wait(lock, [&]{ return val!=old_val; }); // only print if we have a new value
return val;
}();// release lock, no need to hold it while printing
std::cout << new_val << std::endl; // endl flushes. Note there are threading issues streaming to cout like this.
old_val=new_val; // update last printed value
}
}
};
if one thread is printing the other counting, you'll get basically what you want.
When launching a thread with a member function, you need to pass the address of the object, not the object itself
std::thread t2(&Foo::dis, &f);
Please note that this still won't print 1 2 3 4 .. You'll need to have the increment operation and the print alternate exactly for that.
#include <thread>
#include<iostream>
#include <mutex>
std::mutex mtx1, mtx2;
class Foo {
int val;
public:
Foo() : val{0} { mtx2.lock(); }
void inc()
{
for(;;){
mtx1.lock();
++val;
mtx2.unlock();
}
}
void dis()
{
using ms = std::chrono::milliseconds;
for(;;){
mtx2.lock();
std::cout << val <<std::endl;
std::this_thread::sleep_for(ms(200));
mtx1.unlock();
}
}
};
int main()
{
Foo f;
std::thread t1(&Foo::inc, &f);
std::thread t2(&Foo::dis, &f);
t1.join();
t2.join();
}
Also take a look at http://en.cppreference.com/w/cpp/thread/condition_variable
For example, I have two threads, t1 and t2. I want to wait for t1 or t2 to finish. Is this possible?
If I have a series of threads, say, a std::vector<std::thread>, how can I do it?
There's always wait & notify using std::condition_variable, e.g.:
std::mutex m;
std::condition_variable cond;
std::atomic<std::thread::id> val;
auto task = [&] {
std::this_thread::sleep_for(1s); // Some work
val = std::this_thread::get_id();
cond.notify_all();
};
std::thread{task}.detach();
std::thread{task}.detach();
std::thread{task}.detach();
std::unique_lock<std::mutex> lock{m};
cond.wait(lock, [&] { return val != std::thread::id{}; });
std::cout << "Thread " << val << " finished first" << std::endl;
Note: val doesn't necessarily represent the thread that finished first as all threads finish at about the same time and an overwrite might occur, but it is only for the purposes of this example.
No, there is no wait for multiple objects equivalent in C++11's threading library.
If you want to wait on the first of a set of operations, consider having them feed a thread-safe producer-consumer queue.
Here is a post I made containing a threaded_queue<T>. Have the work product of your threads be delivered to such a queue. Have the consumer read off of the other end.
Now someone can wait on (the work product) of multiple threads at once. Or one thread. Or a GPU shader. Or work product being delivered over a RESTful web interface. You don't care.
The threads themselves should be managed by something like a thread pool or other higher level abstraction on top of std::thread, as std::thread makes a poor client-facing threading abstraction.
template<class T>
struct threaded_queue {
using lock = std::unique_lock<std::mutex>;
void push_back( T t ) {
{
lock l(m);
data.push_back(std::move(t));
}
cv.notify_one();
}
boost::optional<T> pop_front() {
lock l(m);
cv.wait(l, [this]{ return abort || !data.empty(); } );
if (abort) return {};
auto r = std::move(data.back());
data.pop_back();
return r;
}
void terminate() {
{
lock l(m);
abort = true;
data.clear();
}
cv.notify_all();
}
~threaded_queue()
{
terminate();
}
private:
std::mutex m;
std::deque<T> data;
std::condition_variable cv;
bool abort = false;
};
I'd use std::optional instead of boost::optional in C++17. It can also be replaced with a unique_ptr, or a number of other constructs.
It's easy to do with a polling wait:
#include<iostream>
#include<thread>
#include<random>
#include<chrono>
#include<atomic>
void thread_task(std::atomic<bool> & boolean) {
std::default_random_engine engine{std::random_device{}()};
std::uniform_int_distribution<int64_t> dist{1000, 3000};
int64_t wait_time = dist(engine);
std::this_thread::sleep_for(std::chrono::milliseconds{wait_time});
std::string line = "Thread slept for " + std::to_string(wait_time) + "ms.\n";
std::cout << line;
boolean.store(true);
}
int main() {
std::vector<std::thread> threads;
std::atomic<bool> boolean{false};
for(int i = 0; i < 4; i++) {
threads.emplace_back([&]{thread_task(boolean);});
}
std::string line = "We reacted after a single thread finished!\n";
while(!boolean) std::this_thread::yield();
std::cout << line;
for(std::thread & thread : threads) {
thread.join();
}
return 0;
}
Example output I got on Ideone.com:
Thread slept for 1194ms.
We reacted after a single thread finished!
Thread slept for 1967ms.
Thread slept for 2390ms.
Thread slept for 2984ms.
This probably isn't the best code possible, because polling loops are not necessarily best practice, but it should work as a start.
There is no standard way of waiting on multiple threads.
You need to resort to operating system specific functions like WaitForMultipleObjects on Windows.
A Windows only example:
HANDLE handles[] = { t1.native_handle(), t2.native_handle(), };
auto res = WaitForMultipleObjects(2 , handles, FALSE, INFINITE);
Funnily , when std::when_any will be standardized, one can do a standard but wasteful solution:
std::vector<std::thread> waitingThreads;
std::vector<std::future<void>> futures;
for (auto& thread: threads){
std::promise<void> promise;
futures.emplace_back(promise.get_future());
waitingThreads.emplace_back([&thread, promise = std::move(promise)]{
thread.join();
promise.set_value();
});
}
auto oneFinished = std::when_any(futures.begin(), futures.end());
very wastefull, still not available , but standard.
I am relatively new to threads, and I'm still learning best techniques and the C++11 thread library. Right now I'm in the middle of implementing a worker thread which infinitely loops, performing some work. Ideally, the main thread would want to stop the loop from time to time to sync with the information that the worker thread is producing, and then start it again. My idea initially was this:
// Code run by worker thread
void thread() {
while(run_) {
// Do lots of work
}
}
// Code run by main thread
void start() {
if ( run_ ) return;
run_ = true;
// Start thread
}
void stop() {
if ( !run_ ) return;
run_ = false;
// Join thread
}
// Somewhere else
volatile bool run_ = false;
I was not completely sure about this so I started researching, and I discovered that volatile is actually not required for synchronization and is in fact generally harmful. Also, I discovered this answer, which describes a process nearly identical to the one I though about. In the answer's comments however, this solution is described as broken, as volatile does not guarantee that different processor cores readily (if ever) communicate changes on the volatile values.
My question is this then: Should I use an atomic flag, or something else entirely? What exactly is the property that is lacking in volatile and that is then provided by whatever construct is needed to solve my problem effectively?
Have you looked for the Mutex ? They're made to lock the Threads avoiding conflicts on the shared data. Is it what you're looking for ?
I think you want to use barrier synchronization using std::mutex?
Also take a look at boost thread, for a relatively high level threading library
Take a look at this code sample from the link:
#include <iostream>
#include <map>
#include <string>
#include <chrono>
#include <thread>
#include <mutex>
std::map<std::string, std::string> g_pages;
std::mutex g_pages_mutex;
void save_page(const std::string &url)
{
// simulate a long page fetch
std::this_thread::sleep_for(std::chrono::seconds(2));
std::string result = "fake content";
g_pages_mutex.lock();
g_pages[url] = result;
g_pages_mutex.unlock();
}
int main()
{
std::thread t1(save_page, "http://foo");
std::thread t2(save_page, "http://bar");
t1.join();
t2.join();
g_pages_mutex.lock(); // not necessary as the threads are joined, but good style
for (const auto &pair : g_pages) {
std::cout << pair.first << " => " << pair.second << '\n';
}
g_pages_mutex.unlock();
}
I would suggest to use std::mutex and std::condition_variable to solve the problem. Here's an example how it can work with C++11:
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
int main()
{
mutex m;
condition_variable cv;
// Tells, if the worker should stop its work
bool done = false;
// Zero means, it can be filled by the worker thread.
// Non-zero means, it can be consumed by the main thread.
int result = 0;
// run worker thread
auto t = thread{ [&]{
auto bound = 1000;
for (;;) // ever
{
auto sum = 0;
for ( auto i = 0; i != bound; ++i )
sum += i;
++bound;
auto lock = unique_lock<mutex>( m );
// wait until we can safely write the result
cv.wait( lock, [&]{ return result == 0; });
// write the result
result = sum;
// wake up the consuming thread
cv.notify_one();
// exit the loop, if flag is set. This must be
// done with mutex protection. Hence this is not
// in the for-condition expression.
if ( done )
break;
}
} };
// the main threads loop
for ( auto i = 0; i != 20; ++i )
{
auto r = 0;
{
// lock the mutex
auto lock = unique_lock<mutex>( m );
// wait until we can safely read the result
cv.wait( lock, [&]{ return result != 0; } );
// read the result
r = result;
// set result to zero so the worker can
// continue to produce new results.
result = 0;
// wake up the producer
cv.notify_one();
// the lock is released here (the end of the scope)
}
// do time consuming io at the side.
cout << r << endl;
}
// tell the worker to stop
{
auto lock = unique_lock<mutex>( m );
result = 0;
done = true;
// again the lock is released here
}
// wait for the worker to finish.
t.join();
cout << "Finished." << endl;
}
You could do the same with std::atomics by essentially implementing spin locks. Spin locks can be slower than mutexes. So I repeat the advise on the boost website:
Do not use spinlocks unless you are certain that you understand the consequences.
I believe that mutexes and condition variables are the way to go in your case.