future
から戻った理由には、将来のデストラクタで発生したstd::async
特別な共有状態があることを知りました。wait on returned future
しかし、 を使用するstd::pakaged_task
と、その future は同じ動作を示しません。パッケージ化されたタスクを完了するには、 からオブジェクトを明示的に呼び出す必要がget()
ありfuture
ますpackaged_task
。
今私の質問は次のとおりです。
- 将来の内部実装は何ですか (思考
std::async
vsstd::packaged_task
)? future
return fromに同じ動作が適用されなかったのはなぜstd::packaged_task
ですか? または、言い換えれば、同じ動作がどのように停止されるのstd::packaged_task
future
でしょうか?
コンテキストを確認するには、次のコードを参照してください。
countdown
タスクが完了するのを待ちません。ただし、コメントを外すと、返された未来を文字通りブロックしているため、// int value = ret.get();
終了し、明らかです。countdown
// packaged_task example
#include <iostream> // std::cout
#include <future> // std::packaged_task, std::future
#include <chrono> // std::chrono::seconds
#include <thread> // std::thread, std::this_thread::sleep_for
// count down taking a second for each value:
int countdown (int from, int to) {
for (int i=from; i!=to; --i) {
std::cout << i << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::cout << "Lift off!" <<std::endl;
return from-to;
}
int main ()
{
std::cout << "Start " << std::endl;
std::packaged_task<int(int,int)> tsk (countdown); // set up packaged_task
std::future<int> ret = tsk.get_future(); // get future
std::thread th (std::move(tsk),10,0); // spawn thread to count down from 10 to 0
// int value = ret.get(); // wait for the task to finish and get result
std::cout << "The countdown lasted for " << std::endl;//<< value << " seconds.\n";
th.detach();
return 0;
}
返されたオブジェクトで使用するかどうかに関係なく、別のスレッドでstd::async
タスクを実行するために使用すると、常にタスクが終了します。countdown
get()
future
// packaged_task example
#include <iostream> // std::cout
#include <future> // std::packaged_task, std::future
#include <chrono> // std::chrono::seconds
#include <thread> // std::thread, std::this_thread::sleep_for
// count down taking a second for each value:
int countdown (int from, int to) {
for (int i=from; i!=to; --i) {
std::cout << i << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::cout << "Lift off!" <<std::endl;
return from-to;
}
int main ()
{
std::cout << "Start " << std::endl;
std::packaged_task<int(int,int)> tsk (countdown); // set up packaged_task
std::future<int> ret = tsk.get_future(); // get future
auto fut = std::async(std::move(tsk), 10, 0);
// int value = fut.get(); // wait for the task to finish and get result
std::cout << "The countdown lasted for " << std::endl;//<< value << " seconds.\n";
return 0;
}