Exception propagation and std::future

2019-04-21 14:09发布

My understanding is that when an asynchronous operation throws an exception, it will be propagated back to a thread that calls std::future::get(). However, when such a thread calls std::future::wait(), the exception is not immediately propagated - it'll be thrown upon a subsequent call to std::future::get().

However, In such a scenario, what is supposed to happen to such an exception if the future object goes out of scope after a call to std::future::wait(), but prior to a call to std::future::get()?

For those interested, here is a simple example. In this case, the exception is silently handled by the thread/future package:

#include "stdafx.h"
#include <thread>
#include <future>
#include <iostream>

int32_t DoWork( int32_t i )
{
    std::cout << "i ==  " << i << std::endl;
    throw std::runtime_error( "DoWork test exception" );
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    auto f = std::async( DoWork, 5 );
    try
    {
        //f.get();     // 1 - Exception does propagate.
        f.wait();      // 2 - Exception does NOT propagate.
    }
    catch( std::exception& e )
    {
        std::cout << e.what() << std::endl;
        return -1;
    }
    return 0;
}

2条回答
地球回转人心会变
2楼-- · 2019-04-21 14:19

vs2012\vc11\crt\future.cpp

there is an error with the

static const char *const _Future_messages[] =
{   // messages for future errors
"broken promise",
"future already retrieved",
"promise already satisfied",
"no state"
};

this code generated an invalid acceso to "_Future_messages" because _Mycode.value() return 4.

    const char *__CLR_OR_THIS_CALL what() const _THROW0()
    {   // get message string
    return (_Get_future_error_what(_Mycode.value()));
    }

// code example

    std::future<int> empty;
try {
    int n = empty.get();
} catch (const std::future_error& e) {
   const error_code eCode = e.code();
   char *sValue = (char*)e.what();
   std::cout << "Caught a future_error with code " << eCode.message()
              << " - what" << sValue << endl;
}
查看更多
beautiful°
3楼-- · 2019-04-21 14:44

It is ignored and discarded, just like if you wait() for a value but never get() it.

wait() simply says "block until the future is ready", be that ready with a value or exception. It's up to the caller to actually get() the value (or exception). Usually you'll just use get(), which waits anyway.

查看更多
登录 后发表回答