我正在看一個頁面上的例子。斯蒂芬·克利裏的書40,爲什麼這裏需要一個鎖?
// 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
。因爲如果我們所做的只是彙總了一組int
s,比如說{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也不完全正確。賦值和加法都是獨立的原子。什麼*不*原子是增量,它由一個讀,一個添加,然後一個賦值組成。每三個操作都是100%原子,但所有三個操作都不是原子的。 – Servy