2016-01-29 49 views
1

任何人都可以用C++中的示例來解釋async([](){x(); y();})async([](){x();}).then([](){y();})之間的區別是什麼?我的理解是,在後一種情況下,x,y中的每一個都可能立即在不同的線程中開始,並且如果在作爲輸入傳遞的將來調用get()時將僅阻塞(在它們各自的線程中)。瞭解std :: future的延續::然後

+0

'then'?那是什麼一個成員函數? – Columbo

+0

如果我沒有錯,它將成爲下一個標準中的std :: future的成員 – Martin

+0

@Columbo:請參見[N3858](https://isocpp.org/files/papers/N3858.pdf)。 –

回答

4

這樣的get()永遠不會阻塞。這是在相關建議N3558中設計的。

#include <future> 
using namespace std; 
int main() { 
    future<int> f1 = async([]() { return 123; }); 

    future<string> f2 = f1.then([](future<int> f) { 
     return f.get().to_string(); // here .get() won’t block 
    }); 
} 

[..]

每個延續不會開始,直到前述已完成。

的好處是,你現在可以在表現手法譜寫幾個異步操作。你能把所有的代碼捆綁到一個lambda中嗎?當然。但是,不可重複使用,也不能特別維護。

此外,還有一些異常處理魔法爲您完成。我建議閱讀定義std::future::then實際上會做什麼的提案,但我承認那裏的「基本原理」部分沒有多少內容:它似乎專注於阻止主線程等待未來完成的缺點,並沒有提到你陳述的替代用例。那麼,也許這就是問題所在:這個功能不是非常想取代它。這就是爲什麼你在努力尋找功能差異。

在異步編程中,一個異步操作在完成時調用第二個操作並將數據傳遞給它是很常見的。目前的C++標準不允許註冊延續到未來。然後,不等待結果,而是繼續「附加」到異步操作,在結果準備就緒時調用異步操作。使用.then函數註冊的繼續將有助於避免在輪詢中阻止等待或浪費線程,從而大大提高應用程序的響應性和可伸縮性。

+1

@immibis:執行「」的函數不會使這些不同的邏輯獨立重複使用,這是我的觀點。如果那些是兩個lambda,那麼你有最大的靈活性,並且可以將它們組合起來,不過你請。 –

+1

這裏是「不可重用」單lambda:'[](){x(); Y(); }'。整個lambda表達式是否可重用,因爲兩個單獨的lambda表達式會是?不,絲毫不重要嗎?不,因爲你仍然可以重用'x'和'y'。 – immibis

+0

@immibis:在這個人爲的例子中,當然,但我假設一個更一般的情況,lambda本身不僅僅是兩個進一步的函數調用。 –

2

...是什麼async([](){x(); y();})async([](){x();}).then([](){y();})之間的區別?

真的不多 - 那爲什麼呢?

單個單詞可組合性。它允許我們在異步環境中以給定問題域的表達方式構建基於模塊化功能(或功能塊)的抽象。

這並不是說一方是對的,另一方是錯的 - 它只是意味着這些語義(.then())在處理異步操作時特別有意義。

單線程計算的語言是「這樣做這樣做這樣做...」,異步計算的語言是‘做到這一點,當它完成,然後此,當它完成,然後這個......’