#include <iostream>
#include <thread>
int x = 0;
int y = 0;
void f()
{
std::cout <<"f called\n";
static int c = 0;
while(y == 0)
{
++c;
}
std::cout << "c=" << c << std::endl;
std::cout << "x=" << x << std::endl;
}
void g()
{
std::cout <<"g called\n";
x = 42;
y = 1;
}
int main()
{
std::thread t1(f);
std::thread t2(g);
t1.join();
t2.join();
return 0;
}
当从另一个线程设置标志y时,f应该打印'x = 42'(好吧,它也打印x = 0,但这不是问题)
在调试模式下运行时,它按预期工作:
f called
g called
c=80213
x=42
但在发布模式下,第二个线程似乎冻结,程序永远不会结束:
f called
g called
有人可以解释一下原因吗?
PS。 该程序使用mignw g ++ 4.8.0编译
答案 0 :(得分:6)
C ++ 11线程内存模型不要求一个线程中的代码会看到由另一个线程中的代码引起的内存更改,除非:
std::mutex
来同步对内存的访问。也就是说,接收线程必须等待写入线程持有的互斥锁。写作线程必须在释放该互斥锁之前写入数据。std::atomic
管理,适当的原子内存访问用于写入和读取。如果这些事情都没有发挥作用,那么一个线程从内存中读取的任何可能被另一个线程修改的尝试都被视为“数据竞争”。因此导致未定义的行为。