ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C++ 多线程使用future传递异常

2021-01-20 22:32:15  阅读:345  来源: 互联网

标签:std set get C++ future promise 多线程 异常


如果 std::async 调用的函数抛出异常,那么这个异常会被存储在值的位置,同时 future 变为 ready ,如果调用 get() 会重新抛出存储的异常。

Note:

标准并没有指定原来的异常对象是被重新抛出或者拷贝后抛出,不同的编译器会做不同的选择。

对于 std::packaged_task<> 包装的函数如果抛出异常,那么处理与 std::async 一致。 std::promise<> 提供类似的机制,如果期望存储一个异常那么在 std::promise<> 对象上就需要使用 set_exception() 代替 set_value()

保存一个异常到 future 中的另外一个方式是在没有调用 std::promise<>set_xxxx 函数或者被 std::packaged_task<> 包装的任务的情况下就销毁与 future 关联的 std::promise<>std::packaged_task<>。无论哪种情况,析构函数都会存储一个错误码是 std::future_errc::broken_promisestd::future_error 异常,表示关联的 future 并没有 ready

#include <iostream>
#include <future>

int main() {
    // std::async
    std::future<void> result1 = std::async([] { 
        throw std::runtime_error("runtime error."); 
    });
    try {
        result1.get();
    } catch (const std::runtime_error &e) {
        std::cout << "Async exception: " << e.what() << std::endl;
    }

    std::promise<int> promise;
    try {
        // 正常的情况就set_value
//        promise.set_value(66);
        // 主动抛出一个异常进行测试
        throw std::out_of_range("the value out of range.");
    } catch (...) {
        // 使用std::current_exception 存储被抛出的异常;
        // 可以使用 std::copy_exception 存储没有被抛出的异常;
        promise.set_exception(std::current_exception());
    }
    try {
        promise.get_future().get();
    } catch (const std::out_of_range &e) {
        std::cout << "Promise exception: " << e.what() << std::endl;
    }

    // 存储异常的其他方式,
    // 在没有调用 std::promise的set_xxx函数
    // 或者没有调用被 std::packaged_task 包装的任务情况下
    // 就销毁与 future关联的 std::promise,std::packaged_task 对象


    // std::packaged_task<>
    std::future<void> future;
    try {
        // 提前销毁task
        {
            std::packaged_task<void()> task([] {
                std::cout << "do packaged task." << std::endl;
            });
            future = task.get_future();
        }
        future.get();
    }
    catch (const std::future_error &e) {
        std::cout << "Packaged task exception: " << e.what() << std::endl;
    }

    // std::promise<>
    try {
        // 提前销毁promise
        {
            std::promise<void> promise;
            future = promise.get_future();
        }
        future.get();
    }
    catch (const std::future_error &e) {
        std::cout << "Promise exception: " << e.what() << std::endl;
    }

    return 0;
}

更多内容:https://blog.nas-kk.top/?p=106

标签:std,set,get,C++,future,promise,多线程,异常
来源: https://www.cnblogs.com/kykx/p/14305465.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有