あなたが知っていることは間違っています。Volatile は、スレッド間のメモリ アクセスの同期、あらゆる種類のメモリ フェンスの適用などには使用されません。メモリに対する操作volatile
はアトミックではなく、特定の順序であるとは限りません。 volatile
言語全体で最も誤解されている機能の 1 つです。" Volatile は、マルチスレッド プログラミングにはほとんど役に立ちません。 "
volatile
使用されるのは、メモリにマップされたハードウェア、シグナル ハンドラー、およびsetjmp
マシン コード命令とのインターフェイスです。
これは、使用されているのと同様の方法で使用することもできます。これが、この記事const
で Alexandrescu が使用する方法です。しかし、間違えないでください。 コードを魔法のようにスレッドセーフにするわけではありません。この特定の方法で使用すると、これは単に、コンパイラーがどこを台無しにした可能性があるかを知らせるのに役立つツールです。間違いを修正するのはあなた次第であり、それらの間違いを修正する役割は果たしません。volatile
volatile
編集:今言ったことについて少し詳しく説明します。
変更できないものへのポインターを持つクラスがあるとします。自然にポインターを const にすることもできます。
class MyGizmo
{
public:
const Foo* foo_;
};
const
ここであなたにとって本当に何をしますか?メモリには何もしません。古いフロッピー ディスクの書き込み禁止タブとは異なります。メモリ自体はまだ書き込み可能です。foo_
ポインターを介して書き込むことはできません。これconst
は、コンパイラに別の方法を提供して、混乱している可能性があることを知らせる方法にすぎません。このコードを書くとしたら:
gizmo.foo_->bar_ = 42;
...マークされているため、コンパイラはそれを許可しませんconst
。const_cast
を使用して -ness をキャストすることでこれを回避できることは明らかですが、const
これが悪い考えであると確信する必要がある場合は、どうしようもありません。:)
Alexandrescu の の使い方volatile
はまったく同じです。何らかの方法でメモリを「スレッドセーフ」にすることは何もしません。それが何をするかというと、失敗した可能性があるときにコンパイラに別の方法で知らせることです。(ミューテックスやセマフォなどの実際の同期オブジェクトを使用して) 真に「スレッドセーフ」にしたものは、 としてマークしますvolatile
。volatile
次に、コンパイラはそれらを非コンテキストで使用させません。コンパイラ エラーがスローされるので、考えて修正する必要があります。volatile
を使用して -ness をキャストすることで再び回避できますがconst_cast
、これは -ness をキャストするのと同じくらい悪ですconst
。
あなたへの私のアドバイスは、あなたが何をしているのか、そしてその理由を本当にvolatile
理解するまで、マルチスレッドアプリケーションを書くツールとして完全に放棄することです (編集:)。ある程度の利点はありますが、ほとんどの人が考えるほどではありません。誤って使用すると、危険なほど安全でないアプリケーションを作成する可能性があります。