Thrown object cannot be caught in a multi-threaded solution

安稳与你 提交于 2019-12-11 03:03:11

问题


I have a RAII class that solves a problem in an inner thread:

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

After creating an instance of it, the main happens to throw an exception. The problem is in some of the executions, the output is:

0

when it always should have been:

0
1
2

In coliru, it is always only 0.

What am I missing here?

PS: Sorry, for the ambiguous title. Please do not hesitate to suggest a better one for this question.


回答1:


You're assuming that the thread will (eventually) see the updated value of alive_. But that's not guaranteed. Objects without synchronisation are not guaranteed to be made visible to other threads in any finite amount of time. It's possible the value of alive_ is cached somewhere and never updated.

You need some synchronisation to make it work—either use a mutex or another synchronisation primitive, or make alive_ atomic. Here's a working example of the latter:

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

Without any synchronisation, the program has Undefined Behaviour, because the two threads enter a data race over alive_.



来源:https://stackoverflow.com/questions/28811830/thrown-object-cannot-be-caught-in-a-multi-threaded-solution

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!