次のようなクラスがあるとします (実際にはちょうどこのサイズです)。
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;
};
ご覧のとおり、これはスレッドセーフである必要があります。更新関数は、一度に 1 つのスレッドによって呼び出されます。不明ですが、1 つのスレッドのみ (保証されます) ですが、アクセサーは同時に複数のスレッドによって呼び出される可能性があります。
update 関数はすべての値を変更しており、非常に頻繁に呼び出されます (1 秒間に 100 回)。ご想像のとおり、現在の実装では多くのロックが発生します。
ロックを回避し、このコードをより効率的にするために std::atomic を使用することを検討していました。ただし、値を一緒に更新するには update 関数が本当に必要です。したがって、代わりに次のようなことを検討しています。
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;
};
std::atomic についての私の現在の理解は、このコードが前のものよりも読みやすい場合でも (どこにでもロック宣言がないため)、K::Data 構造体が「大きい」ため、std::atomic通常のミューテックスロックで実装されるだけです(とにかく、最初の実装よりも高速になるはずはありません)。
私は正しいですか?