【发布时间】:2013-08-22 16:49:10
【问题描述】:
#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编译的
【问题讨论】:
-
数据竞争、未定义的行为等。A.k.a. “多线程真的很难,即使你的 hello world 也会出错。”
-
@Kerrek SB,是的,这绝对是数据竞争条件,但我的问题是,为什么即使 'y' 中的值从 0 变为第一个线程仍然运行?
-
这是“未定义的行为”:任何事情都可能发生。事实上,任何事情都发生了。所以一切都如预期的那样。
-
最有可能的是,编译器看到 while 循环不可能终止,因为
y不是原子的并且循环中没有同步,因此对y的任何修改都将是未定义的,所以它用无限循环替换整个循环。 -
@Sebastian Redl,对此不确定,因为当我在循环中添加 std::cout 时问题消失了.. while(y
标签: multithreading c++11