根据输出的信息,任何人都可以解释以下代码吗?(a==1 && a==2 && a==3)
怎么都正确?
#include <iostream>
#include <thread>
int a = 0;
int main()
{
std::thread runThread([]() { while (true) { a = 1; a = 2; a = 3; }});
while (true)
{
if (a == 1 && a == 2 && a == 3)
{
std::cout << "Hell World!" << std::endl;
}
}
}
输出:
...
2019年一月
我认为这个问题与该链接-> C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?高度相关
最佳答案
您正在遇到未定义的行为。
您的代码具有竞争条件;一个线程正在读取a
,而另一个线程正在写入,因此不会发生同步。您不得在C++中执行此操作。可以将执行此操作的程序编译为可以执行任何操作。
实际上,在发行版上,我希望可以将其编译为if(false)
。编译器优化主线程,不注意同步,证明a没有UB不能是3个不同的值,并优化if
。
在调试版本上,我可以预期到您看到的症状。不是因为它更正确,而是因为调试版本往往不会因这种未定义的行为而跳闸。
因此,合理讨论程序的第一件事是删除未定义的行为:使a
成为std::atomic<int>
而不是int
。
现在,在发行版和调试中,您都希望看到……正是您的测试显示的内容。或者什么都没有。或两者之间的任何东西。结果不再是不确定的,而是不确定的。if
语句不是原子的。在这些条件之间,a
可以更改。随着程序永远运行,它有时应该会发生,因为另一个线程正在对其进行更改。
生成的程序定义良好。 Even forward progress guarantees可以,因为您读取了原子变量。
关于c++ - 谁能解释((a == 1 && a == 2 && a == 3)== true)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52613308/