このサイトにはvolatile
、アトミック/マルチスレッドアクセスに変数を使用できるかどうかを尋ねる質問がいくつかあります。たとえば、ここ、ここ、またはここを参照してください。
さて、C(++)標準準拠の答えは明らかにノーです。
ただし、WindowsおよびVisual C ++コンパイラでは、状況はそれほど明確ではないようです。
最近、MSDNの公式ドキュメントに回答して引用しました。volatile
Microsoft固有
揮発性として宣言されたオブジェクトは(...)
- 揮発性オブジェクトへの書き込み(揮発性書き込み)には、リリースセマンティクスがあります。グローバルオブジェクトまたは静的オブジェクトへの参照?これは、命令シーケンスの揮発性オブジェクトへの書き込みが、コンパイルされたバイナリの揮発性書き込みの前に発生する前に発生します。
- 揮発性オブジェクトの読み取り(揮発性読み取り)には、取得セマンティクスがあります。グローバルオブジェクトまたは静的オブジェクトへの参照?これは、命令シーケンスの揮発性メモリの読み取り後に発生し、コンパイルされたバイナリの揮発性メモリの読み取り後に発生します。
これにより、揮発性オブジェクトをマルチスレッドアプリケーションのメモリロックおよび解放に使用できます。
[私の強調]
さて、これを読むと、揮発性変数はstd::atomic
、次のC ++ 11標準のようにMSコンパイラによって扱われるように思われます。
しかし、私の回答へのコメントで、ユーザーのHans Passantは、「MSDNの記事は非常に残念で、完全に間違っています。Microsoftのバージョンであっても、volatileでロックを実装することはできません。(...)」と書いています。
注意:通常、アトミック交換なしではロックを実装できないため、MSDNに記載されている例はかなり怪しいようです。(Alexも指摘しているように。)これでも疑問が残ります。このMSDNの記事に記載されている他の情報の有効性、特にここやここのようなユースケースの場合。)
さらに、Interlocked *関数のドキュメントがあります。特にInterlockedExchange
、volatile(!?)変数を取り、アトミックな読み取り+書き込みを行います。(SOに関する1つの質問-InterlockedExchangeをいつ使用する必要がありますか? -は、この関数が読み取り専用または書き込み専用のアトミックアクセスに必要かどうかを正式に回答していません。)
さらに、volatile
上記で引用したドキュメントは、「グローバルまたは静的オブジェクト」をほのめかしています。ここでは、「実際の」取得/解放セマンティクスをすべての値に適用する必要があると考えていました。
Windowsでは、Visual C ++(2005-2010)を使用して、(32ビット?int?)変数をvolatile
、この変数へのアトミックな読み取りと書き込みを許可するものとして宣言しますか?
++のWindows / VC上で、私にとって特に重要これが何を保持する(またはしない)べきであるとされている独立プロセッサまたはプラットフォーム上のプログラムの実行の。(つまり、WinXP / 32ビットであるかItanum2で実行されているWindows2008R2 / 64ビットであるかは重要ですか?)
検証可能な情報、リンク、テストケースを使用して回答をバックアップしてください。
はい、それらはwindows / vc ++ではアトミックです(アライメント要件などまたはコースを満たしていると仮定します)
ただし、ロックの場合は、アトミックな更新や読み取りだけでなく、アトミックなテストと設定、またはコンペア・アンド・スワップの命令などが必要になります。
そうでなければ、ロックをテストして、1つの分割できない操作でそれを要求する方法はありません。
編集:以下でコメントするように、32ビット以下のx86でのすべての整列されたメモリアクセスはとにかくアトミックです。重要な点は、volatileによってメモリアクセスが順序付けられることです。(コメントでこれを指摘してくれてありがとう)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加