私はpの例を見ています。ここでロックが必要なのはなぜですか?
// Note: this is not the most efficient implementation.
// This is just an example of using a lock to protect shared state.
static int ParallelSum(IEnumerable<int> values)
{
object mutex = new object();
int result = 0;
Parallel.ForEach(source: values,
localInit:() => 0,
body: (item, state, localValue) => localValue + item,
localFinally: localValue =>
{
lock (mutex)
result += localValue;
});
return result;
}
あるとlock
が必要な理由私は少し混乱しているステファン・クリアリー氏の著書の40。たとえば、int
、つまり{1, 5, 6}
の集計を合計する場合は、共有合計result
を任意の順序でインクリメントする必要はありません。
(1 + 5) + 6 = 1 + (5 + 6) = (1 + 6) + 5 = ...
誰かがここで私の考えが間違っていると説明できますか?
私は、メソッドの本体によって混乱し、ほとんどが単純な追加など
int result = 0;
Parallel.ForReach(values, (val) => { result += val; });
return result;
私は問題を引き起こすその代入演算子を考える。それは自己ではありません。 –
@ M.kazemAkhgaryまた正しくない。割り当てと追加の両方は、それぞれ独立してアトミックです。 *が原子ではないのは、インクリメントです。このインクリメントは、読み込み、追加、割り当てから構成されます。それぞれの3つの操作は100%の原子ですが、3つとも*は原子ではありません。 – Servy