2016-05-31 9 views
3

std::packaged_taskからstd::futureを作成することは安全ですか?別のスレッドで実行されますが、必ずしもその結果を取得するとは限りませんか?std :: futureの結果をstd :: packaged_taskから取得するのは安全ですか?

#include <future> 
#include <thread> 

class Result { 
    Result() {} 
    ~Result() {} 
}; 

void foo() { 
    std::packaged_task<Result()> task(..); 
    auto future = task.get_future(); 
    std::thread thread(std::move(task), ...); 
    thread.detach(); 
    if (future.wait_for(std::chrono::milliseconds(timeout_ms)) == std::future_status::ready) { 
    auto result = future.get(); <--- Task didn't take too long, retrieve future result 
    ... 
    } 
} <--- Task is taking too long, just abort and never call future.get() 
クラン/ libcの++上で動作しているようです

~Result()std::packaged_task天気をによって返される結果に呼び出されたか、最終的にstd::futureで呼び出されていないget()、しかし私は約ドキュメントC++で何かを見つけることができませんでしたので、この使用パターンは、正式にサポートされていることを確認したいと思います。

答えて

0

あなたのプログラムには安全だと思われるものに依存します。あなたが示されたコンテキストの場合
は、それは同様に安全です:

  • futureがそれにgetを行う前に破棄されたときにそれはブロックしません。未来がstd::asyncを使用して作成され、破棄される前にgetを呼び出さないと、結果が利用可能になるまでブロックされていたはずです。次のすべてに該当する場合、それはブロックすることがありますことを除いて、これらのアクションは 、使用可能になるの共有状態をブロックしませんhttp://en.cppreference.com/w/cpp/thread/future/~future

:共有 状態にして
は、ここで、この上でより多くのチェックアウトstd :: asyncの呼び出しで作成された共有状態はまだ ではなく、これは共有状態への最後の参照です。

さて、Resultクラスは非所有のメモリを持っていた場合は何か、手動で解放する必要がありますいくつかの他のリソース(何らかの理由で)。その場合、コードの正確さが疑わしいものになります。より良いことは、ゆっくり動くタスクのためにバックグラウンドスレッドにディスパッチすることです。

+0

本当に 'std :: async'でブロック動作が気づいたので、' std :: packaged_task'に切り替えました。私は、あなたのコードの正しさが疑問に思うのかどうか分かりません。 '〜Result()'が共有状態によっていずれかの方法で呼び出されることが保証されている限り、何が間違っている可能性がありますか? – Pol

+0

Resultクラスがメモリを所有するように設計されているのは確かです。しかし、あなたが所有していないデータを保持しなければならない場合はほとんどありません。そのような場合、 'get_future'を呼び出すのを忘れると正しくないでしょう。それが目的で済むなら(あなたの例のように)、資源がRAIIによって世話をされればそれはおそらく大丈夫です。 – Arunmu

関連する問題