volatileキーワードを使用して、値がいつでも変更される可能性があることをコンパイラに通知します。
volatile int myInteger;
上記により、特定の最適化なしで変数へのアクセスがメモリとの間で行われることが保証されます。その結果、同じプロセッサで実行されているすべてのスレッドは、コードが読み取るのと同じセマンティクスで変数への変更を「認識」します。
Chris Jester-Young は、このような変数値の変更に対するコヒーレンシの問題がマルチプロセッサ システムで発生する可能性があることを指摘しました。これは考慮事項であり、プラットフォームによって異なります。
実際には、プラットフォームに関して考慮すべき点が 2 つあります。それらは、メモリトランザクションの一貫性と原子性です。
原子性は、実際にはシングル プロセッサ プラットフォームとマルチ プロセッサ プラットフォームの両方で考慮すべき事項です。この問題は、変数が本質的にマルチバイトである可能性が高く、問題は、1 つのスレッドが値の部分的な更新を確認できるかどうかであるために発生します。例: 一部のバイトが変更された、コンテキストの切り替え、割り込みスレッドによる無効な値の読み取り。自然な機械語のサイズ以下で、自然に整列された単一の変数の場合、問題になることはありません。具体的には、int型は、アラインされている限り、この点で常に問題ないはずです。これは、コンパイラのデフォルトのケースです。
コヒーレンシに関しては、これはマルチプロセッサ システムで潜在的な懸念事項です。問題は、システムがプロセッサ間で完全なキャッシュ コヒーレンシを実装しているかどうかです。実装されている場合、これは通常、ハードウェアの MESI プロトコルで行われます。質問にはプラットフォームが記載されていませんでしたが、Intel x86 プラットフォームと PowerPC プラットフォームの両方が、通常マップされたプログラム データ領域のプロセッサ間でキャッシュ コヒーレントです。したがって、このタイプの問題は、複数のプロセッサがある場合でも、スレッド間の通常のデータ メモリ アクセスでは問題になりません。
発生する原子性に関連する最後の問題は、読み取り-変更-書き込みの原子性に固有のものです。つまり、値が読み取られて値が更新され、書き込まれた場合、これがアトミックに発生することを保証するにはどうすればよいでしょうか。プロセッサが複数ある場合でも同様です。したがって、これが特定の同期オブジェクトなしで機能するには、変数にアクセスする可能性のあるすべてのスレッドがリーダーのみである必要がありますが、一度にライターになることができるのは 1 つのスレッドだけである必要があります。そうでない場合は、変数への読み取り-変更-書き込みアクションでアトミック アクションを確実に実行できるように、使用可能な同期オブジェクトが必要です。