From lot of threads, like this one, I have found that C# int/float are thread safe. But I have seen lot of developers using Interlocked.Increment/CompareExchage for multi-threaded application. Any one can tell me the reason for using these constructs. Update: I am aware about these constructs. I just wanted to ask If int is thread safe the why we need these constructs?
2 に答える
これらの構造を使用する理由は誰でも教えてくれます。
読み取り/書き込みのスレッドセーフについてではありません。ただし、COMPLETE 操作のスレッド セーフについては。
インクリメントは読み取り、1 加算、書き込みです。1回の「トランザクション」で必ず発生するインターロック付き。比較/交換と同じ。
ある種のロックを使用して記述しないと、操作の合間に中断される可能性があります。
読み取りインクリメント書き込み
3 つのステップはすべてアトミックですが、組み合わせではありません。書き戻すときに他の誰かが値を変更した可能性があります - インターロックにより、WHOLE 操作がアトミックになります。
すでに述べたように、おそらくこれをグーグルで検索したいと思うでしょう。
ただし、「わざわざ InterlockedIncrement(&c.) を使う理由は?」という質問に答えると、int の単純なアクセスはいつでも実行でき、中途半端なものを返さないことが保証されているのは事実ですが、保証はできません。インクリメントなどの「読み取りと変更」操作が期待どおりに機能すること。
InterlockedIncrement とその同類のすべては、操作がアトミックに実行されることを保証します。つまり、InterlockedIncrement 自体の場合、2 つのスレッドが同じ int で呼び出した場合、int は 2 回インクリメントされ、正しい値が返されることが保証されます。呼び出しスレッド。ただし、単純な「i++;」を実行すると、同時に 2 つのスレッドで (同じ 'i' に対して) 読み取ると、誤った値が読み取られる可能性があります。
これは、'i++' などのインクリメントが、少なくとも 2 つの機械語命令 (「値の読み取り」と「値のインクリメント」) に分割されるためです (さらに悪い場合は、「読み取り」、「ローカル値のインクリメント」、「書き込み」)。 . 両方のスレッドがまったく同時にこれを行うと、両方とも値 0 を読み取る可能性がありますが、インクリメントされた値は最終的に 2 になる可能性があります。