Kis*_*Yoo 1 c++ multithreading c++11 stdthread
根据输出信息,任何人都可以解释下面的代码?
怎么可能都是(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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
Run Code Online (Sandbox Code Playgroud)Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World!
...
2019年1月
我认为这个问题与这个链接高度相关 - > C++ 11引入了标准化的内存模型.这是什么意思?它将如何影响C++编程?
Yak*_*ont 10
您遇到了未定义的行为.
您的代码有竞争条件; 一个线程正在读取a而另一个线程正在写入,并且不会发生同步.您不能在C++中执行此操作.执行此操作的程序可以编译为执行任何操作.
实际上,在发布版本中,我希望编译到if(false).编译器优化主线程,注意没有同步,证明a不能是没有UB的3个不同的值,并优化了if.
在调试版本中,我可以预期您看到的症状.不是因为它更正确,而是因为调试版本往往不会超过这种未定义的行为.
所以你要合理地谈论你的程序要做的第一件事就是删除未定义的行为:make aa std::atomic<int>而不是a int.
现在在发布和调试中,您都希望看到......正是您的测试显示的内容.或无.或者介于两者之间.结果不再是未定义的,但仍然是不确定的.
该if声明是不是原子.条件之间,a可以改变.随着程序永远运行它有时会发生,因为另一个线程正在改变它.
由此产生的程序定义明确. 即使是前进进度保证也没问题,因为你读了一个原子变量.