简体   繁体   English

同时读取写入的成功

[英]Success of write with simultaneous read

If one thread in a program attempts to read from a variable while another writes to it, the value read is of course undefined. 如果程序中的一个线程尝试从另一个变量读取而另一个线程写入变量,则读取的值当然是未定义的。 However, assuming there is only one writer, is the write guaranteed to succeed? 但是,假设只有一个作者,写保证成功吗? For example: 例如:

bool myGlobalVariable = false;
void thread1() {
    myGlobalVariable = true;
}
void thread2() {
    bool x = myGlobalVariable; //x is undefined
}

In this case, once both threads are finished, is myGlobalVariable guaranteed to be true ? 在这种情况下,一旦两个线程都完成, myGlobalVariable保证是true

I'm specifically wondering about gcc on linux, but I'd be interested to know what other operating systems and compilers do, or if ARM behaves differently than x86. 我特别想知道linux上的gcc,但我有兴趣知道其他操作系统和编译器的作用,或者ARM的行为是否与x86不同。

In practice nothing probably will fail. 在实践中,没有什么可能失败。 However, the C++11/14 standard is pretty clear in this regard. 但是,C ++ 11/14标准在这方面非常清楚。 Here is a quote from C++14 draft section [intro.multithread]/23 (emphasis mine): 以下是C ++ 14草案部分[intro.multithread]/23 (强调我的)的引用:

The execution of a program contains a data race if it contains two potentially concurrent conflicting actions, at least one of which is not atomic, and neither happens before the other, except for the special case for signal handlers described below. 程序的执行包含数据竞争,如果它包含两个可能同时发生冲突的动作,其中至少有一个不是原子的,并且除了下面描述的信号处理程序的特殊情况之外,它们都不会发生在另一个之前。 Any such data race results in undefined behavior. 任何此类数据争用都会导致未定义的行为。

Where conflicting actions are defined at [intro.multithread]/6 : [intro.multithread]/6中定义冲突行为的地方:

Two expression evaluations conflict if one of them modifies a memory location (1.7) and the other one accesses or modifies the same memory location. 如果其中一个修改内存位置(1.7)而另一个访问或修改相同的内存位置,则两个表达式评估会发生冲突

I can't see how this could possibly fail to write the value under any circumstances, if it's just a write and not a read. 我无法看到在任何情况下,如果它只是一个写而不是一个读,这可能无法写入该值。

The reason that multithreaded access to the same variable is dangerous is precisely that there's no checking being done as to whether the variable is being modified during an operation. 对同一变量进行多线程访问的原因很明显,就是在操作期间是否正在修改变量时, 不会进行检查 It's not that it might check and then complain. 这不是它可能检查然后抱怨。

So in the case of a single write, and just a write (so no i++ , which is a read as well), it must succeed. 因此,在单个写入的情况下,只是一个写入(所以没有i++ ,这也是一个读取),它必须成功。

Of course, you could design hardware that would fail if you wanted to, but I don't see how any standard architecture could fail. 当然,如果您愿意,可以设计出会失败的硬件,但我不知道任何标准架构如何失败。

As Anton points out in his answer, the spec says it's undefined behaviour, and so it would be possible to write a valid C++ compiler that deliberately watches out for such behaviour and randomises the result. 正如Anton在他的回答中指出的那样,规范说它是未定义的行为,因此有可能编写一个有效的C ++编译器,故意注意这种行为并随机化结果。 But no compiler is going to do that in practice. 但是在实践中没有编译器会这样做。

That said, it's never a good idea to rely on behaviour that's officially undefined, so as the comment from jeffamaphone says, the right answer to your question is that the write will succeed, but you still shouldn't do it. 也就是说,依靠官方未定义的行为绝不是一个好主意,所以正如jeffamaphone的评论所说,你的问题的正确答案是写作会成功,但你仍然不应该这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM