[解決済み] なぜvolatileはマルチスレッドのCやC++のプログラミングで有用ではないと考えられているのですか?
質問
で示したように
この回答
先日投稿した、実用性(またはその欠如)について混乱しているようです。
volatile
マルチスレッドプログラミングのコンテキストで
私の理解では、変数にアクセスするコードの制御の流れの外で変数が変更される可能性がある場合は、その変数は、以下のように宣言する必要があります。
volatile
. シグナルハンドラ、I/Oレジスタ、他のスレッドによって変更された変数などは、すべてこのような状況に該当します。
つまり、もしグローバルな int
foo
であり、かつ
foo
があるスレッドによって読み込まれ、別のスレッドによって(おそらく適切な機械命令を使って)アトミックに設定された場合、読み込んだスレッドはこの状況を、シグナルハンドラによって調整された変数や外部のハードウェア条件によって変更された変数を見るのと同じように見て、その結果
foo
を宣言する必要があります。
volatile
(または、マルチスレッド環境では、メモリフェンシングロードでアクセスするのがより良い解決策でしょう)。
どこがどう間違っているのでしょうか?
どうすればいい?
の問題は
volatile
をマルチスレッドコンテキストで提供しないことです。
すべて
を保証するものです。必要なプロパティはいくつかありますが、全てではありません。
volatile
単独
.
しかし、そのために使わなければならないプリミティブは
残り
プロパティが提供するものも
volatile
が行うので、事実上不要です。
共有データへのスレッドセーフなアクセスには、次のような保証が必要です。
- 読み書きが実際に行われること(コンパイラが値をレジスタに格納し、メインメモリの更新をずっと後まで延期することはないこと)
-
並べ替えが行われないこと。仮に
volatile
このフラグは、あるデータが読み込める状態にあるかどうかを示すものである。このコードでは、データを準備した後にフラグをセットするだけなので、すべての ルックス となります。しかし、もし命令の順番を変えて、フラグがセットされるようにしたらどうでしょう 最初 ?
volatile
は、最初の点を保証しています。また、並べ替えが発生しないことも保証しています。
異なる揮発性の読み取り/書き込みの間
. すべて
volatile
のメモリアクセスは、指定された順番で発生します。これだけで、何のために
volatile
は、I/O レジスタやメモリマップド・ハードウェアを操作するためのものですが、マルチスレッドコードで
volatile
オブジェクトは、しばしば不揮発性データへのアクセスを同期させるためにのみ使用されます。これらのアクセスは、まだ
volatile
のものがあります。
並べ替えを防止するための解決策としては メモリバリア ということをコンパイラとCPUの両方に示します。 このポイントでは、メモリアクセスの順序を変更することはできません。 . このようなバリアを揮発性変数アクセスの周囲に置くことで、不揮発性アクセスも揮発性変数に順番が入れ替わることがなくなり、スレッドセーフなコードを書くことができるようになります。
ただし、メモリバリア
また
は、バリアに到達したときに保留中のすべての読み取り/書き込みが実行されることを保証するため、それだけで必要なものを効果的に提供し
volatile
は不要です。このまま
volatile
という修飾子があります。
C++11以降、アトム変数(
std::atomic<T>
によって、関連するすべての保証が得られます。
関連
-
[解決済み】C++ - 解放されるポインタが割り当てられていないエラー
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】関数名の前に期待されるイニシャライザー
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] volatileキーワードは何に役立つのでしょうか?
-
[解決済み] iostream::eof がループ条件の中 (つまり `while (!stream.eof())`) にあるのはなぜいけないとされているのでしょうか?
-
[解決済み] なぜsizeof(x++)はxをインクリメントしないのですか?
-
[解決済み] なぜalloca()の使用はグッドプラクティスとみなされないのでしょうか?
-
[解決済み] <bits/stdc++.h> を #include しない方が良いのでしょうか?
-
[解決済み】揮発性のあるものはなぜ存在するのか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】テンプレートの引数1が無効です(Code::Blocks Win Vista) - テンプレートは使いません。
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み】C++プログラムでのコンソールの一時停止
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)