为什么需要锁?

时间:2016-12-30 23:36:32

标签: c# .net parallel-processing

我正在看一个关于p的例子。斯蒂芬克莱里的40本书是

IFrequency

我有点困惑为什么需要// 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,那么我们就不需要关心以任何顺序递增的共享和{1, 5, 6}

result

有人可以解释我的思想存在缺陷吗?

我想我对方法的身体有点困惑不能简单地

(1 + 5) + 6 = 1 + (5 + 6) = (1 + 6) + 5 = ...

3 个答案:

答案 0 :(得分:10)

添加等操作不是 atomic ,因此不是线程安全的。在示例代码中,如果省略了锁,则完全有可能在几乎同时执行两个加法运算,导致其中一个值被覆盖或错误地添加。有一种 线程安全的方法可以增加整数:.text-shop-button { -fx-text-fill: white; -fx-background-image: url("../resources/Game/button.png"); -fx-min-height: 40px; -fx-min-width: 120px; -fx-max-height: 40px; -fx-max-width: 120px; -fx-focus-color: transparent; -fx-faint-focus-color: transparent; -fx-background-position: center; } .text-shop-button:pressed { -fx-min-height: 36px; -fx-min-width: 108px; -fx-max-height: 36px; -fx-max-width: 108px; -fx-font-size: 90%; -fx-background-position: center; -fx-background-size: 90%; } 。但是,由于没有使用,因此在示例代码中需要锁定以确保一次完成一个非原子加法操作(按顺序而不是并行)。

答案 1 :(得分:7)

它不是关于'result'更新的顺序,更新它的race condition,记住运算符+=不是原子的,所以两个线程可能看不到另一个线程的udpate在他们触摸它之前

答案 2 :(得分:3)

语句result += localValue;实际上是在说result = result + localValue;您正在阅读和更新由不同线程共享的资源(变量)。这很容易导致竞争条件。 lock确保在任何给定时刻该语句由单个线程访问。