Reputation: 2257
Is there a C++ language feature for thread-safe class member variables? A quick search or two revealed nothing, but I thought it was pretty simple and came up with this solution.
template <class T>
class ThreadSafeVar
{
private:
T safeVar;
std::mutex accessMutex;
public:
ThreadSafeVar(T initialValue) { safeVar = initialValue; }
ThreadSafeVar<T>& operator=(const T &source) { set(source); return *this; }
ThreadSafeVar<T>& operator=(ThreadSafeVar<T> &source) { set(source.get()); return *this; };
void set(T newValue)
{
std::lock_guard<std::mutex> lock(accessMutex);
safeVar = newValue;
};
T const get(void)
{
std::lock_guard<std::mutex> lock(accessMutex);
return safeVar;
};
};
Is there anything wrong with this solution (possible deadlocks, etc.)? Does C++ already have a method for doing this?
Upvotes: 1
Views: 2828
Reputation: 111
Refer to std::atomic and std::memory_order.
The following is an example you can try with g++ -std=c++ atomic_example.cpp
.
#include <atomic>
#include <iostream>
#include <thread>
class ThreadSafeVar {
public:
ThreadSafeVar() { var_.store(0, std::memory_order::memory_order_relaxed); }
~ThreadSafeVar() {}
void Add() { var_.fetch_add(1, std::memory_order::memory_order_acquire); }
long Get() { return var_.load(std::memory_order_acquire); }
private:
std::atomic<long> var_;
};
void Foo(ThreadSafeVar& var) {
long i = 0;
while (i++ < (1l << 20)) {
var.Add();
}
}
int main(int argc, char* argv[]) {
ThreadSafeVar var;
std::thread thr1 = std::thread(Foo, std::ref(var));
std::thread thr2 = std::thread(Foo, std::ref(var));
thr1.join();
thr2.join();
std::cout << "var = " << var.Get() << "\n";
return 0;
}
Upvotes: 2
Reputation: 53
There is nothing wrong with your code. For the the trivially copiable types there is std::atomic.
Upvotes: 0