の定義はstd::atomic<>
、プリミティブ型またはおそらく POD 型に対する明らかな有用性を示しているようです。
実際に授業で使用するのはいつですか?
クラスでの使用 を避けるべき場合はいつですか?
の定義はstd::atomic<>
、プリミティブ型またはおそらく POD 型に対する明らかな有用性を示しているようです。
実際に授業で使用するのはいつですか?
クラスでの使用 を避けるべき場合はいつですか?
std::atomic
簡単にコピー可能なタイプで利用できるようにする操作は、かなり基本的なものです。構築して破棄したりatomic<T>
、タイプを尋ねたり、のis_lock_free()
コピーをロードして保存したり、さまざまな方法T
での値を交換したりできT
ます。それがあなたの目的にとって十分であるならば、あなたは明示的なロックを保持するよりもそれをするほうがよいかもしれません。
これらの操作が十分でない場合、たとえば、値に対して直接シーケンス操作をアトミックに実行する必要がある場合、またはオブジェクトが十分に大きいためにコピーにコストがかかる場合は、代わりに、管理する明示的なロックを保持する必要があります。より複雑な目標を達成するため、または使用atomic<T>
に伴うすべてのコピーを実行しないようにするため。
// non-POD type that maintains an invariant a==b without any care for
// thread safety.
struct T { int b; }
struct S : private T {
S(int n) : a{n}, b{n} {}
void increment() { a++; b++; }
private:
int a;
};
std::atomic<S> a{{5}}; // global variable
// how a thread might update the global variable without losing any
// other thread's updates.
S s = a.load();
S new_s;
do {
new_s = s;
new_s.increment(); // whatever modifications you want
} while (!a.compare_exchange_strong(s, new_s));
ご覧のとおり、これは基本的に値のコピーを取得し、コピーを変更してから、変更された値をコピーして戻し、必要に応じて繰り返します。コピーに加える変更は、単一のメンバー関数に限定されるだけでなく、必要に応じて複雑にすることができます。
プリミティブおよび POD タイプで機能します。タイプはmemcpy
-able でなければならないので、より一般的なクラスは出ていません。
標準はそれを言う
アトミック テンプレートの特殊化とインスタンス化には、削除されたコピー コンストラクター、削除されたコピー代入演算子、および constexpr 値コンストラクターが必要です。
それがピート・ベッカーの答えと厳密に同じかどうかはわかりません。私はこれを、(memcpy 対応のクラスだけでなく) 独自のクラスに自由に特化できるように解釈します。