0

スレッド間でワード変数を共有するマルチスレッド アプリケーション (つまり、32 ビット システムで 32 ビット データ型) を使用している場合、そのワードの読み取りと書き込みをミューテックスで保護する必要がありますか?

4

2 に答える 2

2

キャッシュ、マルチコア、アウトオブオーダー実行などについて話すのではなく、ミューテックス (または割り込み操作などの他の相互排除技術) を使用する理由を説明するために、簡単な例を提供します。 )

変数を 1 ずつインクリメントするには (少なくとも最近私が扱っているほとんどのアーキテクチャでは)、値をメモリからレジスタに読み取り、レジスタ内の値を調整して、メモリに書き戻す必要があります。優先度の高い A と優先度の低い B の 2 つのスレッドがあるとします。次のシナリオを考えてみましょう。

  • スレッド B は、メモリからレジスタに "x" を読み取ります (値は 5)。
  • スレッド B はレジスタを値 6 にインクリメントします。
  • スレッド A はスレッド B を横取りします。
  • スレッド A は "x" をレジスタに読み取ります (メモリ内の値はまだ 5 ですよね?)。
  • スレッド A はレジスタを値 6 にインクリメントします。
  • スレッド A が値 6 をメモリに書き戻す
  • スレッド A はスリープ状態になります。
  • スレッド B が起動し、そのレジスタ値 6 をメモリに書き戻します。

両方のスレッドが値を増やしましたが、値は 1 つしか上がりませんでした。

これがエレベーターの階数、感知された心拍数、またはスペースシャトルのカウントダウン値 (OK、それは減分になります) である場合、問題が発生する可能性があります。

このインクリメント操作をアトミックに実行できるアーキテクチャ (通常は CISC) がいくつかあることに注意してください。

注: 場合によっては (ただしこれは行わないでください)、ライターが 1 つとリーダーが複数ある場合は、ミューテックスなしで済むことがあります。たとえば、ISR がティック カウントなどをインクリメントし、他のスレッド/タスクが頻繁にアクセスして読み取ります。

私が言いたいのは、共有データを保護しなくても済むと思っていても、常にそれを保護することは良い考えだということだと思います。「コマンドー」を実行したい場合は、自分が何をしているのかを本当に知っている必要があります。それでも、同じコードが明日新しいアーキテクチャに移植されたときに壊れる可能性があります。

于 2011-01-28T03:43:25.600 に答える
2

一般に、はい、アクセスをミューテックスと同期する必要があります。メモリ位置への書き込みが「アトミック」であると思われる場合でも、CPU はそのメモリへの読み取りと書き込みの命令を並べ替え、望ましくない動作を引き起こす可能性があります。また、マルチコアまたはマルチ CPU システムでは、共有メモリの場所への書き込みは、同期しないと他のコア/CPU からすぐには認識されない場合があります。

詳細については、ウィキペディアのMemory Barrierの記事を参照してください。

于 2011-01-28T00:46:49.293 に答える