首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >科技促进发展:期货和例外

科技促进发展:期货和例外
EN

Stack Overflow用户
提问于 2017-03-07 12:29:19
回答 1查看 1.6K关注 0票数 6

给定以下源代码

代码语言:javascript
复制
#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。在将异常传播到主线程之后,未来的状态不会失效。这是一个错误,还是我在这里遇到了未定义的行为?

EN

回答 1

Stack Overflow用户

发布于 2017-03-07 12:42:12

我好像是个虫子。

根据 documentation的说法,valid()应该在调用get之后返回false

任何共享状态都会被释放。在调用此方法后,valid()false

深入了解一下VC++实现get,就会发现一个bug:

代码语言:javascript
复制
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);
        }

基本上,如果_Retreived持有true,那么_Exception也应该被设置为exception_ptr。在抛出时,这个变量从未设置过。看起来,当他们测试它时,他们并没有为一个现成的未来进行测试,而只是为了不成熟的未来进行测试,因为后者不会显示这个bug。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42648352

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档