如果程序中的一个线程试图从一个变量读取而另一个线程写入该变量,则读取的值当然是未定义的。但是,假设只有一个作者,写保证成功吗?例如:
bool myGlobalVariable = false;
void thread1() {
myGlobalVariable = true;
}
void thread2() {
bool x = myGlobalVariable; //x is undefined
}
在这种情况下,一旦完成两个线程,myGlobalVariable
保证是true
吗?
我特意想知道linux上的gcc,但我有兴趣了解其他操作系统和编译器的作用,或者ARM的行为是否与x86不同。
答案 0 :(得分:2)
在实践中,没有什么可能会失败。但是,C ++ 11/14标准在这方面非常清楚。以下是C ++ 14草案部分[intro.multithread]/23
(强调我的)的引用:
程序的执行包含数据竞争,如果它包含两个可能同时发生冲突的动作,其中至少有一个不是原子动作,并且在其他动作之前都不会发生,除了特殊情况信号处理程序如下所述。 任何此类数据争用都会导致未定义的行为。
在[intro.multithread]/6
:
两个表达式评估冲突如果其中一个修改了内存位置(1.7),另一个访问或修改了相同的内存位置。
答案 1 :(得分:1)
如果它只是一个写入而不是一个读取,我无法看到在任何情况下这可能无法写入该值。
对同一变量的多线程访问是危险的原因恰恰在于,在操作期间是否正在修改变量没有检查。它不是可以检查然后抱怨。
所以在单次写入的情况下,只是一次写入(所以没有i++
,这也是一个读取),它必须成功。
当然,如果您愿意,您可以设计出会失败的硬件,但我不知道任何标准架构可能会失败。
正如Anton在他的回答中指出的那样,规范说明了它的未定义行为,因此有可能编写一个有效的C ++编译器,故意注意这种行为并随机化结果。但是在实践中没有编译器会这样做。
也就是说,依靠正式未定义的行为绝不是一个好主意,所以正如jeffamaphone的评论所说,你的问题的正确答案是写作会成功,但是你仍然不应该这样做。