c++ - std::futures 和异常

标签 c++ multithreading exception std-future

给定以下源代码

#include <thread>
#include <future>
#include <iostream>
#include <string>
#include <chrono>

int main() {

    auto task = std::async(std::launch::async, [] {       
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        throw std::runtime_error("error");
    });


    try {
        while (task.wait_for(std::chrono::seconds(0)) !=std::future_status::ready)
        {
            std::cout << "Not ready: " << std::endl;
        }
        task.get();
    }
    catch (const std::exception& e)
    {
        std::cout << "Valid: " << task.valid() << std::endl;
    }

}

我希望程序会以 Valid: 0 响应。使用 g++ 6.2.0 就是这种情况。但是,使用 MS VS2015 版本 14.0.25431.01 更新 3,响应为 Valid: 1。在异常传播到主线程后, future 的状态不会失效。这是一个错误还是我在这里遇到未定义的行为?

最佳答案

我好像是个 bug 。

根据 std::future::get documentation , valid() 应在调用 get 后返回 false

Any shared state is released. valid() is false after a call to this method.

深入研究 get 的 VC++ 实现,那里有一个错误:

virtual _Ty& _Get_value(bool _Get_only_once)
        {   // return the stored result or throw stored exception
        unique_lock<mutex> _Lock(_Mtx);
        if (_Get_only_once && _Retrieved)
            _Throw_future_error(
                make_error_code(future_errc::future_already_retrieved));
        if (_Exception)
            _Rethrow_future_exception(_Exception);
        _Retrieved = true;
        _Maybe_run_deferred_function(_Lock);
        while (!_Ready)
            _Cond.wait(_Lock);
        if (_Exception)
            _Rethrow_future_exception(_Exception);
        return (_Result);
        }

基本上,如果 _Exception 持有 exception_ptr,则 _Retreived 也应设置为 true。到抛出时,此变量从未设置。看起来当他们测试它时,他们并没有为一个现成的 future 而测试, 仅适用于未就绪的 future ,因为后者不会显示此错误。

关于c++ - std::futures 和异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42648352/

相关文章:

c++ - 遇到提取或插入运算符时,编译器处理信息(字符串、操纵符等)的顺序是什么?

c++ - C++ 中的虚拟网络摄像头

java - 服务器和线程模型

exception - 如何在 Haskell 中重新抛出通用异常

C#,自定义异常的使用

c++ - 即使委托(delegate)仅添加到 QTableView,QListView 项目也显示委托(delegate)编辑器

c++ - 该程序应显示输入等于倒数

python - 在python中使用threading/multiprocessing同时进行多个计算

java - 如何在 SWING 中执行时停止代码块

java - 抛出意外的令人困惑的错误