2016-03-24 8 views
3

質問 破壊時にstd :: future call wait()またはget()は実行されますか?std :: futureは破棄時に待機する

void fun() 
{ 
    std::future<int> fut = my_thread_pool.submit(some_work); 
}//is fut.wait() or fut.get() called? here 
+0

なぜそうする必要がありますか?結果を使用しないと結果が利用可能になるのを待つ必要があるのはなぜですか? – user463035818

+3

'std :: async'によって作成された場合にのみブロックされます。 – Simple

+2

はいの場合を除き、答えはいいえです。 –

答えて

3

から:The View from the C++ Standard meeting September 2013 Part 2 of 2.

非同期デストラクタは、我々はそれを議論の 多くを捧げブロックしてはならないという問題では。 [..] を受け取った唯一のポジションは、将来のデストラクタ が非同期から返されない限り、ブロックされないように勧告していて、それは注目に値する 例外になっています。 [..]重要な議論の後、 が実行しようとした唯一の部分はN3776でした。 〜futureと〜shared_futureは非同期の の存在を除いてブロックされません。 Cの 行に沿って非推奨を発行しようとしましたが、置き換えを行わずに非同期を非難しました。この動きは実際にはほとんど でした。しかし、[...]それは 手術台に達する前に亡くなった。

もチェック:非同期で返さN3679: Async() future destructors must wait

を基本的な問題

先物()準備になるために関連した共有状態のための彼らの デストラクタでの非同期起動ポリシー待ちと。この は、関連付けられたスレッドが継続して実行される状況を防止するために、 と関連付けられた未来が破棄されているため、完了するまで待機する手段がなくなりました。 が完了するのを待つことなく、そのような「逃げ出した」スレッドは、それが依存するオブジェクトの寿命を過ぎて実行することができます。 一例として、機能の次のペアを検討

:no_join_async場合

void f() { 
    vector<int> v; 
    ... 
    do_parallel_foo(v); 
    ... 
} 

void do_parallel_foo(vector<int>& v) { 
    auto fut = no_join_async([&] {... foo(v); return ...; }); 
    a: ... 
    fut.get(); 
    ... 
} 

は、()は、そのデストラクタ 非同期完了を待たずに、将来を返すのコードが をスローするまで、すべてがうまくいくことがあり例外。その時点では、非同期が完了するのを待つ時間はなく、 です。do_parallel_foo() とf()の両方の出口を過ぎても実行され続けるため、非同期タスクがメモリにアクセスしてオーバーワイトされます。 。

最終的な結果は、同様の条件でN2802に記載されているものと同様の と同様のクロススレッドの「メモリ破損」である可能性があります。

no_join_async()で生成された先物が破棄される前にget()またはwait()が呼び出されると、この問題は回避されます。 N2802のように、予期しない例外によってそのコードがバイパスされる可能性があります。したがって、ある種のスコープガードは、通常、安全を確保するために必要な です。プログラマがスコープ ガードを追加することを忘れた場合、攻撃者は、例えば、 a bad_alloc例外は、適切な時点で、 監視を利用して、スタックを上書きする原因となります。 もスタックを上書きするために使用されるデータを制御する可能性があります。したがって、プロセスを制御して を取得してください。これは十分に微妙なエラーで、 の経験では、実際のコードで見落とされる可能性があります。

+0

私は正しく理解しています。答えはそれが依存しているということです。 – user1235183

+1

@ user1235183: - はい、そう言うことができます:) –

+0

_standard_を引用してください。これは、実際の行動の権威ある宣言ではありません。 –