[英]How exactly std::async is executed?
我想知道以下代碼如何工作?
#include <thread>
#include <future>
#include <set>
#include <iostream>
struct Task;
std::set<const Task*> dead_tasks;
struct Task
{
~Task() { dead_tasks.insert(this); std::cout << "dtor\n";}
Task() { std::cout << "ctor\n";}
Task(Task&&) { std::cout << "move-ctor\n";}
void operator()() const { std::cout << "func()\n"; }
};
int main(){
std::cout << dead_tasks.size() << '\n';
std::async(std::launch::async, Task());
std::cout << dead_tasks.size() << '\n';
}
此代碼打印
0 ctor move-ctor move-ctor dtor func()dtor dtor 3
如果我們使用std :: launch :: deferred而不是std :: launch :: async,我們將得到
0 ctor move-ctor move-ctor dtor dtor dtor 3
因此,在后者中,我們錯過了成員函數調用。 為什么? 我可以理解是否存在對默認構造函數的調用和對move構造函數的調用。 Task()調用默認的構造函數,然后std :: async調用move構造函數...但是,我錯過了第二次調用move構造函數和調用成員函數背后的想法。 我可以認為第二步構造函數是由std :: future調用的,不是嗎?
因此,在后者中,我們錯過了成員函數調用。 為什么?
因為通話被推遲了。 它只會在您實際請求其結果后才開始,例如,通過在將來調用get()
(您沒有):
auto fut = std::async(std::launch::deferred, Task());
fut.get();
我可以認為第二步構造函數是由std :: future調用的,不是嗎?
這是由實現定義的,是否以及將有多少個復制構造函數調用。 例如用clang編譯它甚至給了我三個調用move-constructor的調用。 因此,不要理會它。 但是,如果這樣做,您必須自己研究標准庫的實現(如果有)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.