Edit2: 申し訳ありませんが、役に立ちません。アクセスの周りにミューテックスが必要です-コンパイラが生成したコードがポインタをレジスタ[またはレジスタのないプロセッサの場合はスタックなどの他のストレージ]にロードし、ポインタが指すメモリにアクセスする可能性があります(非常に可能性が高い)同時に、ポインターは別のスレッドによって更新されています。ポインターが正しいことを保証する唯一の方法は、ミューテックスまたは同様の構造を使用して、アクセスのブロック全体を閉じることです。それ以外は失敗する可能性があります。
syam が言うように、標準では、ポインターが指す 32 ビット値の読み取りでさえアトミックであることを保証していません。それはシステムの実装に依存しています。ただし、「古い値または新しい値のいずれかの値を取得できますか」という質問がある場合は、少なくとも x86 および x86-64 がそれを保証します。他のマシン アーキテクチャではそうではない可能性があります (SMP 68000 プロセッサでの 32 ビット int 実装では保証されません。書き込みは一度に 16 ビットであり、2 番目のプロセッサがその半分を書き込んでいる可能性があるためです)。 68000 プロセッサを搭載した SMP システムが構築されていることは知っています)。
( InterlockedExchange
「標準」関数ではない) は、このスレッドのプロセッサがポインタ自体に排他的にアクセスできることを保証するため、安全に実行できます。他のプロセッサはその時点でポインタにアクセスできません。これが、x86 アーキテクチャの「ロックされた」命令の要点です。それらは「安全」です (かなり遅いですが、毎回これを実行しないと仮定すると...)。
commonPointer
編集:コンパイラは、別のスレッドを使用して更新していることを認識しない可能性があるため、それ自体に注意する必要があることに注意してください。そのため、まだ OLD ポインター値から読み取っている可能性があります。
[何もインライン化されていない]関数への呼び出し、またはポインターの宣言はvolatile int * volatile commonPointer;
、そのトリックを行う必要があります。[「誰かが以前に投稿したようvolatile
に解決策がある問題はないので、を使用するための私の答えに反対票を投じる人をキューに入れます]。volatile
[上記の edit2 を参照]