1
#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编译

4

1 回答 1

6

C++11 线程内存模型不要求一个线程中的代码会看到由另一个线程中的代码引起的内存更改,除非

  1. 这两个线程通过使用std::mutex. 也就是说,接收线程必须等待写入线程持有的互斥锁。并且写入线程必须在释放该互斥体之前写入数据。
  2. 有问题的内存由 管理std::atomic,并使用适当的原子内存访问对其进行写入和读取。

如果这些事情都没有发生,那么一个线程从内存中读取可能被另一个线程修改的任何尝试都被认为是“数据竞争”。因此会导致未定义的行为。

于 2013-08-22T08:37:31.997 回答