3

コンパイラは終了future直後にfutureのデストラクタを呼び出すべきではありません。つまり、とにかく呼び出されるmain関数であるべきではありませんか?f()(gcc 4.7.2はそれを行いません)。

#include <iostream>
#include <thread>
#include <future>

using namespace std;

void f() {
    cout << "thread...\n";
}

int main() {
    auto future = async(&f);
    cout << "I am main\n";
}

編集:私はのみ Hello from main取得します。テキストthread...はまったく印刷されません。

編集2:将来のデストラクタは呼び出しますwait()か?

4

2 に答える 2

8

注意:以下の古い情報(C ++ 14より前)。最新情報については、Jonasの回答を参照してください。


メインが終了した直後に、コンパイラが将来のデストラクタを呼び出さないようにする必要があります

終了する 直前main。でも、はい。

つまり、とにかく関数f()を呼び出すべきではありませんか?

いいえ、なぜですか?のデストラクタがstd::futureそうするだろうとあなたはどう思いますか?これはデストラクタの仕事ではありません。実際、§30.6.6/ 9によると、デストラクタの唯一の機能は、将来の共有状態を解放して破壊すること*thisです。これ以上何もない。

于 2012-11-29T22:27:00.120 に答える
2

これは将来の話です(しゃれを意図しています):

FWIW、コンラッドの答えはC++11にのみ当てはまります。C ++ 14では、この動作が変更されました。cppreferenceによると:

これらのアクションは、共有状態の準備が整うまでブロックしません。ただし、次のすべてが当てはまる場合はブロックする可能性があります。共有状態はstd :: asyncの呼び出しによって作成され、共有状態はまだ準備ができていません。共有状態への最後の参照でした。

上記の引用では起動ポリシーについては言及されていませんが、タスクが非同期で起動された場合にのみ、この動作を確認できました。私のテストによると、明示的に待たされることのない先物は、先物std::async(std::launch::deferred, ...)の破壊時に評価されないようです。

また、これはから作成された先物にのみ関係するため、追加のがのデストラクタに平手打ちされstd::asyncた場合はほとんどないことに注意してください。wait();std::future

最後に、Boost 1.73の時点では、によって作成された場合、同様の変更は行われませんでした。つまり、BoostバージョンはC++14以前と同じように動作します。boost::futureboost::async(boost::launch::async, ...)std::future

于 2020-05-14T09:27:43.037 に答える