そう思うのは私だけでしょうか?[すぐに本当の質問です。]
それについての大きな混乱と、ミューテックスや他のロックメカニズムとの混合に加えて、スレッドセーフの状況を扱っているときは、 の使用を常に破棄する必要がvolatile
あります。
volatile
volatile
「読み取り/書き込みの並べ替えやキャッシュを禁止します」が、これは、単一のオブジェクトにタグを付けるだけである限り、あまり役に立ちません(「通常の」オブジェクトではなくなるため、それを汚染します)。
このことを考慮:
Thread A Thread B
reads vars
locks mutex (gets access)
locks mutex (waits)
writes some vars
releases mutex
reads vars again
releases mutex
ここで、コンパイラは 2 つのスレッド A の読み取りを最適化し、結果の一部をレジスタに保存する必要がある場合があります。あなたは、それらの vars を として宣言する必要があると言いますvolatile
。は石のように透過的であり、型をサポートするためにコードの 50% を複製する必要があるvolatile
ため、すべてを としてフラグ付けしたくないと言います。あなた(彼volatile
volatile
)ミューテックス(少なくともPOSIXミューテックス)のロックは、コンパイラーが認識して正しく管理するものであるか、世界を変える可能性のあるライブラリ(コンパイラーにアクセスできない)への呼び出しであるため、コンパイラーは想定しないそのような電話の後は何でも。私は、これは実装に依存しすぎており、非常に低レベルのものだと言っています (そして、日々のプログラミングのために開発ドキュメントを参照したくありません)。さらに悪いことに、何らかの理由で「外部ライブラリ」が正当な理由でコンパイラにアクセスできるようになった場合、突然変更される可能性があります(おそらく、作成者はヘッダーに含める必要があるテンプレートで関数を変換します...何でも) .
したがって、私の意見でvolatile
は、非常に低レベルのもの(おそらくデバイスの読み取りですが、私はそのような分野では能力がありません)を除いて、まったく役に立たない(そして誤解を招く)ものです。
変数に関する仮定を破棄する必要があり、その後のすべての読み取りはメモリからの真の読み取りでなければならないことをコンパイラーに明示的に伝える別の方法の方がはるかに優れています。しかし、ダミーの外部関数を呼び出すよりも良いことは想像できません。それには、以前に概説したのと同じ問題があります。そうするエレガントな方法はありますか?