更新:私は別の形式でこの質問をしました(以下を参照)、そしてそれは建設的ではなかったために閉じられました。答えが私が尋ねたものを正確に扱っていたので(そして私の問題を解決したので)ちょっと残念ですが、私はここで新しいので、私は確かにそれをより建設的にするためにもう一度試みます。
私はWindows7のVC++で作業しています。マルチスレッドプログラムは、1つのスレッドの変数に値を割り当て、イベントオブジェクトを介して、ブロックされている別のスレッドに信号を送信し、その信号を待ちます。コンパイラによって提供される最適化などの理由により、一方のスレッドが(ブロッキングメカニズムを介して)もう一方のスレッドが試行しないことが確実な場合でも、一方のスレッドによって変数に割り当てられたデータが実際にもう一方のスレッドで利用できるという保証はありません。データが変数に割り当てられた後までアクセスします。たとえば、値がCPUレジスタにあり、そのレジスタが他の何かに必要になるまでそこにとどまる場合があります。これにより、値がそのレジスタに入れられた直後に再び必要になった場合に、メモリからの不要なロードを回避できます。不運にも、つまり、メモリ内の対応する場所は、新しい値が割り当てられる前に保持していた最後の値を保持し続けます。したがって、他のスレッドがブロックを解除し、変数の値を保持しているメモリにアクセスすると、最近割り当てられた値ではなく、古い値。
問題は、あるWindowsスレッドが変数に割り当てた値のメモリにストレージを強制し、別のスレッドが後でそれらに確実にアクセスできるようにする方法です。いくつかの答えがあるかもしれませんが、この質問が閉じられる前に提供されたものは、私が必要としたものに最も適していると思われました。これは、以前は聞いたことのないプログラミング構造である「メモリフェンス」の使用でした。フェンスに遭遇した後、メモリへの保留中の書き込みが完了したことが保証されます。(これは、フェンスが「書き込み」フェンスの場合です。「読み取り」フェンスを使用してメモリからの読み取りを強制でき、「読み取り/書き込み」フェンスを使用して両方を実行できます。Windowsでは、VC++内で3つすべてを非常に簡単に使用できます。プログラム。)
ちょっとした落とし穴の1つは、Windowsフェンス(別名「メモリバリア」)が保証をグローバルストレージにのみ適用し、ローカルストレージには適用しないことです(該当するMSDNページで説明されている理由により)。
ここでのメモリフェンスの仕組みに関する私の解釈が正しくない場合(そしてモデレーターがこの質問を再び開く場合)、コメントで説明されているのを見てうれしく思います。結局のところ、私が知らなかったことを認めるほど謙虚でなかったかどうかは尋ねません。(モデレーターが再度開いていないのに、何か問題があることがわかった場合は、メールを送って知らせてください。ブログでこのディスカッションを継続できるようにサポートさせていただきます。もし、するなら。)
元のバージョン
スレッド間でデータを共有するための良い方法は何ですか?
先ほど、私にとって大きな学習体験を開く変数について質問しました。volatile
とりわけ、私は正しい質問をしていないことに気づきました。これが悪いスタックオーバーフローのエチケットではないことを願っていますが、私の根本的な問題に対処する新しい質問をここに作成する必要があると思います:
Visual C ++プログラムには、AとBの2つのスレッドがあります。Bはブロックされ、Aからの信号を待機します。Aはいくつかの変数を設定します。次に、AはBに信号を送り、Aによって設定された変数を読み取ります。Aによって設定された変数の一部は、CPUレジスタにのみ存在する可能性があるため、実際にはメモリに書き戻されない可能性があります。
スレッドBが、スレッドAによって以前に設定された変数を読み取るときに、スレッドAが設定した値を読み取ることを確認するための良い方法は何ですか?