我試圖測驗std::shared_future不同執行緒之間的共享方式,因為這些執行緒都呼叫了它的函式,并在它被呼叫wait()后喚醒。signal如下:
#include <iostream>
#include <future>
using namespace std;
int main() {
promise<void> p, p1, p2;
auto sf = p.get_future().share(); // This line
auto f1 = [&]() {
p1.set_value();
sf.wait();
return 1;
};
auto f2 = [&]() {
p2.set_value();
sf.wait();
return 2;
};
auto ret1 = async(launch::async, f1);
auto ret2 = async(launch::async, f2);
p1.get_future().wait();
p2.get_future().wait();
p.set_value();
cout << ret1.get() << ", " << ret2.get();
return 0;
}
該程式列印1, 2并運行良好。
然后我將行auto sf = p.get_future().share();改為auto sf = p.get_future()使用oridinayfuture物件,而不是shared版本,編譯并運行。我得到了相同的結果:雖然我預計對于非共享版本,只有 1 個執行緒會成功wait并回傳,而其他執行緒會掛起。但似乎程式運行正常。
所以我的問題是:我們什么時候需要使用std::shared_future而不是std::future?或者它只是一個像std::shared_ptr, 作為一個簡單的包裝器std::future以便它可以被傳遞的物件?
我的意思是在任何情況下非共享未來都不能滿足需求或場景。你能幫忙解釋一下嗎?
uj5u.com熱心網友回復:
的“共享”部分shared_future不是等待而是獲取。
我預計對于非共享版本,只有 1 個執行緒會成功等待并回傳,而其他執行緒會掛起。
不,這是完全安全的,您可以從任意數量的執行緒中等待未來(它是一個 const 成員,因此是執行緒安全的),并且在設定結果時都必須解除阻塞。但請注意,wait()不能在有人呼叫后呼叫get()。
不同之處在于您如何獲得結果。請記住,std::future代表未來的結果集std::promise。
std::future::get()按值回傳。它只能被呼叫一次,因此只能從一個執行緒呼叫。std::shared_future::get()回傳一個常量參考。它可以從多個執行緒中多次呼叫。當然要小心底層物件的執行緒安全——它的方法是否真的是執行緒安全的。
此外std::shared_future,可以克隆并且多個這樣的物件可以參考單個共享狀態,即鏈接到單個承諾物件。只要某些未來/承諾指向它,共享狀態就存在,例如std::shared_ptr<State>.
在您的情況下,您有點濫用std::shared_future sf,等待結果的每個執行緒都應該獲得自己的克隆。這樣,它的生命周期是安全的。設想的作業流程是:
std::promise被創建,[first]future是從中獲得的。- 承諾是給生產者的,消費者不知道。
- 未來被賦予[每個]消費者[可以克隆它并在必要時傳遞它]。
我的意思是在任何情況下非共享未來都不能滿足需求或場景。你能幫忙解釋一下嗎?
有兩個消費者執行緒,都在等待結果。std::future將需要一個執行緒呼叫get并以某種方式與另一個執行緒共享該結果。盡管兩者都可以呼叫wait()。另一方面std::shared_future,允許兩者都“查看”結果,因為它是 const。是的,如果需要傳遞結果,則必須復制結果,但無論如何這是不可避免的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/513364.html
標籤:C c 11承诺未来共享
