抛出的对象不能在多线程解决方案中捕获 [英] Thrown object cannot be caught in a multi-threaded solution

查看:179
本文介绍了抛出的对象不能在多线程解决方案中捕获的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

创建它的实例后,main会抛出异常。问题是在一些执行中,输出是:

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

当它应该是:

0
1
2

coliru ,它总是只有 0

我在这里缺少什么?

PS:对不起,

推荐答案

您假设线程将(最终)看到更新的 alive _ 值。但这不是保证。没有同步的对象不保证在任何有限的时间内对其他线程可见。 alive _ 的值可能会被缓存到某处,从不更新。

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.

您需要一些同步才能使其工作。使用互斥或​​另一个同步原语,或使 alive _ 原子。以下是后者的工作示例

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

没有任何同步,程序有未定义行为,因为两个线程在 alive _

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

这篇关于抛出的对象不能在多线程解决方案中捕获的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆