了解为什么只有一个线程执行写操作时会发生竞争条件

Understanding why race condition happens when only one thread does the write operation

我最近问了“”并得到了完美的正确答案。但是,我仍然很困惑为什么只有一个线程执行写操作时会出现竞争条件。让我贴一下原来有问题的代码:

#include <iostream>
#include <thread>
using namespace std;

struct solution_using_thread {
    solution_using_thread()
     : alive_(true), thread_() {
        thread_ = thread([this]() {
            while(alive_);
        });
    }
    ~solution_using_thread() {
        alive_ = false;
        thread_.join();
    }
private:
    bool alive_;
    thread thread_;
};

int main() {
    cout << 0 << endl;
    try {
        solution_using_thread solution;
        throw 1;
    } catch (int i ) {
        cout << i << endl;
    }
    cout << 2 << endl;
}

有时输出只有

0

根据链接的问题,如果我改为使用成员 atomic<bool> alive_,输出将变为预期的结果

0
1
2

现在,我正在尝试解释成员 bool alive_ 导致未定义行为的原因。

案例 1(大团圆结局):

情况2(不希望,但至少'Undefined Behavior'):

显然,至少还有一种情况只打印 0。你能描述一下那个案例吗?

标准说,如果多个线程访问一个变量并且至少有一个访问是写入,那么如果该变量不是原子的并且操作没有顺序,则存在数据竞争,并且程序具有数据竞争具有未定义的行为。

了解这些规则,编译器可以假定非原子变量不会被乱序修改(否则 任何 程序都是对源代码的有效解释);在您的示例代码中,这意味着编译器可以简单地假设 alive_ 在繁忙的循环中永远不会改变——尽管顺便说一句,像这样的非终止循环本身就是未定义的行为。