Suppose that I have a class that looks like this (actually exactly this size):
class K
{
public:
long long get_x() const; // lock m_mutex in shared/read-only mode
void update( long long w ); // lock m_mutex with a unique_lock
private:
long long m_a;
long long m_b;
long long m_c;
long long m_x;
double m_flow_factor;
mutable boost::shared_mutex m_mutex;
};
As you can see, this should be thread-safe. The update function is called by one thread at a time, unknown but only one thread (guaranteed), but the accessor can be called by several threads at the same time.
The update function is changing all the values and is called very often (a hundread times a second). Current implementation will, as you can guess, locks a lot.
I was considering using std::atomic to avoid locks and potentially make this code more efficient. However, I really need the update function to update the values together. Therefore, I am considering doing something like this instead:
class K
{
public:
long long get_x() const
{ return data.load().x; }
void update( long long w )
{
auto data_now = data.load();
// ... work with data_now
data.store( data_now );
}
private:
struct Data {
long long a;
long long b;
long long c;
long long x;
double flow_factor;
};
std::atomic<Data> data;
};
My current understanding of std::atomic is that, even if this code is more readable than the previous one (because it don't have lock declarations everywhere), as the K::Data struct is "big", std::atomic will just be implemented with a normal mutex lock (so it shouldn't be faster than my initial implementation anyway).
Am I correct?