【发布时间】:2015-07-10 23:02:57
【问题描述】:
我在我正在阅读的一本教科书中发现了这个问题。解决方案也在下面给出。我无法理解最小值如何为 2。为什么一个线程不能读取 0,而所有其他线程都执行并写入 1?而不管是1还是2,最后写的线程还必须完成自己的循环?
int n = 0;
int main(int argc, char **argv) {
for (i = 0; i < 5; i++) {
int tmp = n;
tmp = tmp + 1;
n = tmp;
}
return 0;
}
如果一个线程运行这个应用程序,你会期望最终 输出为 5。如果 5 个线程并行运行同一个循环会怎样?什么 n 可以有的最大值和最小值是多少?最大的应该 不言而喻:25,5 个线程的 5 个增量。然而, 推理最小的可能值更加困难。提示:n 可能小于 5,但由您自己找出原因。
解决方案:
五个线程运行这个五次迭代循环并且没有 防止并发访问,n 可以达到的最低值 是两个。工作时最容易理解如何达到这个结果 从最终结果倒退。为了最终输出为两个,a 线程必须从 n 中读取值 1,将其递增,然后 写了两个。这意味着另一个线程写了一个,这意味着 它最初也读为零(这也是 n 的起始值)。 这解释了五个线程中的两个线程的行为。然而, 要发生这种行为,其他三个线程的结果必须 已被覆盖。两个有效的处决可以实现这一点。 要么 1) 所有三个线程开始并完成之间的执行 第一个线程读取零并写入一个,或 2) 所有三个线程 在最后一个线程读取 1 和 写两个。两个执行顺序都有效。
【问题讨论】:
-
嗯,这只会导致未定义的行为,在 C11 线程中,因为没有使用内存栅栏或原子。
-
@MattMcNabb 是的。我也应该包括第一部分。 “您已经看到来自多个线程的不安全访问会导致不可预知的结果。但是您也看到可以从不安全访问中提取一些保证(也就是说,如果每个线程都写入 1,那么最终值不能神奇地变成其他值)。考虑以下代码 sn -p:"
-
@UserNotDefined:绝对错误。如果每个线程都写入 1,并且存在导致未定义行为的竞争条件,则结果可以是任何东西。您的应用程序可能会崩溃。
标签: c multithreading concurrentmodification