首页 > 解决方案 > 为承诺设置例外会导致中止调用

问题描述

我有一个投掷功能:

void calculateValuesThrowing(std::promise<int>&& pr, int a, int b)
{
    try
    {
        auto timeout = std::chrono::seconds(5);
        logInfo("Calculating value...");
        std::this_thread::sleep_for(timeout);
        if (a == b)
        {
            throw std::runtime_error("a cannot equal b");
        }
        pr.set_value(a + b);
    }
    catch(std::exception& exc)
    {
        pr.set_exception(std::current_exception()); // ok, jump here right after the "throw" above
    }
}

我这样称呼它:

main() 函数中的某处:

try
{
    std::promise<int> promise;
    auto future = promise.get_future();
    std::thread th(calculateValuesThrowing, std::move(promise), 10, 10);
    auto result = future.get();
    th.join();
}
catch(std::exception& exc)
{
    std::cout << "Error:" << exc.what(); // never get there
}

我希望calculateValuesThrowing的异常将被“重新抛出”,以便我可以在 main 的 catch() 中处理它,但是在calculateValuesThrowing完成工作后我得到abort()

我究竟做错了什么?

标签: c++exceptionpromise

解决方案


future.get()抛出时,th.join()永远不会被调用,因此th在线程仍处于活动状态时超出范围。这将终止程序

试试[原文如此]这样的东西:

std::promise<int> promise;
auto future = promise.get_future();

std::thread th(calculateValuesThrowing, std::move(promise), 10, 10);
try
{
    auto result = future.get();
}
catch(std::exception& exc)
{
    std::cout << "Error:" << exc.what(); // never get there
}

th.join();

当然,现在你不能result在 之外使用try,但无论如何都是这样。我没有足够的信息来说明您如何使用它来建议具体的解决方法。


推荐阅读