抛出的 object 无法被 multi-threaded 解决

Thrown object cannot be caught in a multi-threaded solution

我有一个 RAII class 解决了内部线程中的一个问题:

#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;
}

在创建了它的一个实例之后,main恰好抛出了一个异常。问题出在某些执行中,输出为:

0

当它总是应该是:

0
1
2

coliru中总是只有0.

我在这里错过了什么?

PS:抱歉,标题含糊不清。请不要犹豫,为这个问题提出更好的建议。

您假设线程将(最终)看到 alive_ 的更新值。但这并不能保证。没有同步的对象 not 保证在任何有限的时间内对其他线程可见。 alive_ 的值可能缓存在某个地方并且永远不会更新。

您需要一些同步才能使其工作——要么使用互斥体或其他同步原语,要么使 alive_ 原子化。这是后者的 working example

#include <atomic>

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

没有任何同步,程序有未定义的行为,因为两个线程在 alive_ 上进入数据竞争。