防止线程在处理异常后分离时调用 std::terminate()

2024-03-01

我有自己的线程类,旨在帮助安全地管理异常。它看起来像这样:(为了简单起见,跳过了其他构造函数和互斥体)

class ExceptThread
    : public std::thread {
public:
    template<typename Func, typename... Args>
    ExceptThread(Func&& f, Args&&... args)
        : std::thread([] (Args&&... args) {
        try {
            return f(args...);
        } catch(...) {
            exc = std::current_exception();
        }
    }, args...) { }
    // skipped other constructors etc.
    //...    
    void check() { 
        if(exc) { 
            std::exception_ptr tmp = exc; 
            exc = nullptr; 
            std::rethrow_exception(tmp); 
        } 
    }

private:
    std::exception_ptr exc;
};

这个类的用法如下:

ExceptThread et([] { std::this_thread::sleep_for(5s); throw std::runtime_error("Ugly exception"); });

try {
    while(/*...*/) {
        // main loop
        et.check();
    }
} catch(std::exception& e) {
    // do sth
}

Problem:

当线程抛出异常时,它会被捕获catch(...)并保存到exc, 一切安好。但当执行更进一步std::terminate就像没有捕获异常一样被调用。我还尝试暂停子线程(例如Sleep(INFINITE)) 捕获异常后但是std::terminate()在分离线程时被调用std::thread::~thread()在主线程中堆栈展开期间。我怎样才能阻止系统这样做?

平台:MSVC

相似的:如何在线程之间传播异常? https://stackoverflow.com/questions/233127/how-can-i-propagate-exceptions-between-threads


您必须在销毁线程之前显式加入线程,这有助于防止在销毁线程之前忘记中断线程时潜在的死锁/崩溃(在我使用的每个实现中,std::terminate 消息中都说明了这一点) 。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

防止线程在处理异常后分离时调用 std::terminate() 的相关文章

随机推荐

  • Unix 中的 Chrome Headless 返回空页面源

    我正在使用 Chrome Headless 在 Unix 机器 Cent OS 中运行我的硒测试脚本 但是相同的脚本在我的本地 Windows 机器上完美运行 但在 Unix 机器中 它返回空页面源 如空 html 标签 尽管我使用最新的
  • JTable 多标题行

    I am using a JTable in my application and wish to have 2 rows for headings similar to this 这是否可能 或者我必须做其他事情吗 如果是这样 那又怎样
  • 如何将 Sass Eyeglass 与 Webpack 结合使用?

    我想用萨斯眼镜 https github com sass eyeglass eyeglass with Webpack https webpack js org 我发现有关它的信息很少 并且相当令人沮丧 因为我确信它可以完成 有人使用它取
  • 协方差在这里安全吗?

    class Food class Meat extends Food class Animal void feed Food f class Lion extends Animal void feed Meat m void foo Ani
  • 如何从 ManagedBean 获取 primefaces 数据表列顺序和宽度

    我正在使用 primefaces 4 0 JSF Mojarra 2 2 2 这是我的数据表代码
  • 如何解决 OpenSSL::Cipher::Cipher#encrypt 的弃用警告

    我刚刚将 Mac 升级到 Snow Leopard 并启动并运行了 Rails 环境 除了 OSX 之外 与我之前安装的唯一区别是我现在正在运行ruby 1 8 7 2008 08 11 patchlevel 72 universal da
  • 找不到页面 (404)

    Error Request Method GET Request URL http 192 168 100 10 accounts profile Using the URLconf defined in urls Django tried
  • 在无需访问 Internet 的情况下从 EC2 实例使用 AWS CLI

    有没有办法使用AWS CLI从EC2 linux实例调用不同的服务 例如SQS EC2 SNS 调用 AWS CLI 命令的 EC2 实例无法访问互联网 它位于私有子网中 它不使用互联网网关或 NAT Thanks 不可能 CLI 必须访问
  • 棘手的 CRC 算法

    我正在尝试找到适用于以下结果的 crc 字节串由 2 个字节组成 即 0xCE1E crc 是单个字节 即 0x03 byte crc CE1E 03 CE20 45 CE22 6F 0000 C0 0001 D4 FFFF 95 有人可以
  • Perl 的未来? (Perl 6,就业能力)

    我发现了一些相关的问题 比如Python 与 Perl https stackoverflow com questions 150043 python v perl 现已删除 和Perl 值得吗 https stackoverflow co
  • Google 地图上的多个标记:仅显示最后一个标记

    我在地图上显示多个标记时遇到问题 该代码首先循环遍历一个数组 然后对纬度 经度值进行反向地理编码 然后显示标记并将 infoWindow 的内容设置为返回的地址 我的代码如下 for var i 0 i lt useNowArray len
  • @tailrec 如何工作

    我已经使用并阅读了 tailrec注释具有尾递归方法 我浏览了许多解释它的链接 例如 它仅在自调用函数时有效 并且不应被覆盖等 到处都提到compiler optimizes 但是编译器做了什么魔法 概念来使其成为尾递归 对于下面的简单函数
  • 无法从 powershell 运行 Elixir 应用程序

    当我打字时iex S mix在 PowerShell 中我收到此错误 Invoke Expression A positional parameter cannot be found that accepts argument mix At
  • 每行后动态重复标题行

    如何在 gridview 的每一行之后重复标题行 您可以将代码添加到网格的 rowdatabound event 中 protected void GridView RowDataBound object sender GridViewRo
  • Extjs XTemplate 两个同级数组循环?

    我想将 XTempate 与以下 json 数据一起使用 在另一个数组中循环一个数组 var data name xxx rowTitleArr 1 2 3 colTitleArr a b c var tpl name
  • 如何压缩包含超过 12GB 数据的文件夹

    我需要压缩一个包含大量文件的文件夹 当我尝试在命令行中进行压缩时 它显示压缩错误 输入文件读取失败 我搜索网络并发现 ZIP 文件格式 仅处理可以的文件长度 包含在 32 位整数中 如果是这样 那么它一定是我收到错误的原因 因为我的文件夹大
  • 如何使用asihttprequest接受自签名证书

    我正在尝试获取自签名证书来使用我的应用程序 我现在正在使用 ASIHTTPRequest 库 如下所示 IBAction sendHttpsRequest Set request address NSMutableString databa
  • 现在 CGI 脚本有哪些用途?

    我非常熟悉一般的 Web 编程语言 但我现在使用的工具之一是 CGI 我只能说 CGI 脚本相当慢 CGI 如今仍然普遍使用吗 如果不是的话 被什么取代了 是否存在 CGI 仍然存在并被积极使用的利基功能 CGI是协议 它是创建动态页面最基
  • 使用循环合并和创建表

    我尝试搜索如何使用循环合并和创建多个表 但找不到我正在寻找的内容 我有四个表 表 1 1 1 2 1 3 和表 2 表1 1 1 2和1 3共享相同的列但具有不同的行 表 2 与表 1 1 1 2 和 1 3 具有相同的第一列 具体来说 表
  • 防止线程在处理异常后分离时调用 std::terminate()

    我有自己的线程类 旨在帮助安全地管理异常 它看起来像这样 为了简单起见 跳过了其他构造函数和互斥体 class ExceptThread public std thread public template