2013-01-08 15 views
8

私の理解では、非同期操作で例外がスローされると、それはstd::future::get()を呼び出すスレッドに伝播されます。しかし、そのようなスレッドがstd::future::wait()を呼び出すと、例外は即座に伝播されません。それは、その後のstd::future::get()の呼び出しでスローされます。例外の伝播とstd :: future

std::future::wait()の呼び出しの後で、将来のオブジェクトが範囲外になる場合、そのようなシナリオでは、std::future::get()の呼び出しの前に、そのような例外が発生するはずのことはありますか?

興味のある方は、ここに簡単な例があります。この場合、例外は黙ってスレッド/将来のパッケージによって処理されます:

#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; 
} 
+0

私は例外に何も起こりません、それは単に無視されます。 (しかし私はこれで十分であるとは限りません) – Mat

+1

例外は 'std :: exception_ptr'sによってスレッド間で伝播されることに注意することが重要です。したがって、システムには例外がキャッチされ、伝播メカニズムが再スローすることを決定するまで例外が処理されるように見えます。 –

答えて

12

それだけで価値のために、あなたの場合wait()決してget()それのように、無視されて破棄されます。

wait()は、単に「将来の準備ができているまでブロックする」と言っていますが、それは値または例外で準備ができている必要があります。値(または例外)を実際にget()に送信するのは、呼び出し側の責任です。とにかく待つのはget()です。

+0

ガー!私はこれを買いますが、特にstd :: asyncによって作成されたstd :: futureにvoid型の結果型がある場合は混乱します。そのような未来のためにget()を呼び出すことは奇妙に感じます。 – Bukes

+4

@Bukes:Heh私はそれを見ることができた。しかし、 'future 'を '' T'の結果として考えるのではなく、 '' T''を計算した結果と考えてください。もちろん例外です。 – GManNickG

+0

@GManNickG関数がvoidを返す場合はどうしたらget()の代わりにwait()を呼び出すことは意味がないと思います – Kapil

0

vs2012 \ VC11の\陰極線管の\ future.cpp

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

このコードにエラーがあるが _Mycode.value()リターン4ので無効アクセソに "_Future_messages" を生成しました。 //コード例

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

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; 
}