簡介:
本篇文章,我們詳細的介紹下c++標準庫提供的線程同步方法中的第3個——future。
參見【并發(fā)編程九】c++線程同步——互斥(mutex)
二、條件變量參見【并發(fā)編程十】c++線程同步——條件變量(condition_variable)
三、future類模板 std::future 提供訪問異步操作結果的機制:
注意, std::future 所引用的共享狀態(tài)不與另一異步返回對象共享(與 std::shared_future 相反)。
1、promise備注:簡單來說,就是以下過程
#include#include#includeusing namespace std;
void task(int a, int b, promise& p)
{p.set_value(a + b);
}
int main()
{// 把promise和future做關聯(lián)
promisep;
futuref=p.get_future();
thread task1(task,1,2,ref(p));
//do somesthing
//get promise value
f.wait();
cout<< "return value is "<< f.get()<< '\n';//只能get一次。
task1.join();
}
1.2、主線程設置值,子線程獲取
#include#include#includeusing namespace std;
void task(int a, future& b, promise& p)
{p.set_value(a + b.get());
}
int main()
{// 把promise和future做關聯(lián)
promisep_ret;
futuref_ret=p_ret.get_future();
promisep_in;
futuref_in = p_in.get_future();
thread task1(task,1,ref(f_in),ref(p_ret));
//do somesthing
//...
p_in.set_value(3);
//get promise value
f_ret.wait();
cout<< "return value is "<< f_ret.get()<< '\n';//只能get一次。
task1.join();
}
2、async
異步運行一個函數(shù)(有可能在新線程中執(zhí)行),并返回保有其結果的 std::future.
2.1、不開新線程的async#include#include#includeusing namespace std;
int task(int a, int b)
{return a + b;
}
int main()
{// 把async和future做關聯(lián)
futuref = async(task, 1, 5);
//get future value
f.wait();
cout<< "return value is "<< f.get()<< '\n';
}
2.2、開新線程的async
#include#include#includeusing namespace std;
int task(int a, int b)
{return a + b;
}
int main()
{// 把async和future做關聯(lián)
futuref = async(launch::async,task, 1, 5);
//get future value
f.wait();
cout<< "return value is "<< f.get()<< '\n';
}
3、packaged_task輸出結果和不開線程一樣的
#include#include#includeusing namespace std;
int task(int a, int b)
{return a + b;
}
int main()
{// 調用packaged_task的構造函數(shù),返回值和兩個參數(shù)都是int類型,
packaged_taskt(task);
//執(zhí)行
t(5,5);
// 把packaged_task和future做關聯(lián)
futuref = t.get_future();
//獲取返回值的結果
f.wait();
cout<< "return value is "<< f.get()<< '\n';
}
輸出
3.2、提前指定參數(shù)
#include#include#includeusing namespace std;
int task(int a, int b)
{return a + b;
}
int main()
{// 調用packaged_task的構造函數(shù),返回值和兩個參數(shù)都是int類型,
packaged_taskt(std::bind(task,11,12));
//執(zhí)行
t();
// 把packaged_task和future做關聯(lián)
futureresult = t.get_future();
//獲取返回值的結果
result.wait();
cout<< "return value is "<< result.get()<< '\n';
}
3.3、bind
bind返回參數(shù)為std::function
#include#include#includeusing namespace std;
int task(int a, int b)
{return a + b;
}
int main()
{// bind返回值為std::function,
auto a = bind(task, 11, 14);
//執(zhí)行
int result = a();
cout<< "return value is "<< result<< '\n';
}
備注:既然bind就可以獲取結果,為何還要用packaged_task,當然是因為future啊。
4、shared_future#include#include#includeusing namespace std;
mutex mtx;
void task(int a, shared_future& b, promise& p)
{p.set_value(2);
b.wait();
int bb = b.get();
lock_guardguard(mtx);
cout<< "task b ="<< b.get()<// 把promise和future做關聯(lián)
promisep_ret_1,p_ret_2;
futuref1 = p_ret_1.get_future();
futuref2 = p_ret_2.get_future();
promisep_in;
shared_futures_f = p_in.get_future();
thread task1(task, 1, ref(s_f), ref(p_ret_1));
thread task2(task, 2, ref(s_f), ref(p_ret_2));
//do somesthing
f1.wait();
f2.wait();
//...
p_in.set_value(3);
//get promise value
{lock_guardguard(mtx);
cout<< "main() return value is "<< f1.get()<< '\n';//只能get一次。
cout<< "main() return value is "<< f2.get()<< '\n';//只能get一次。
}
task1.join();
task2.join();
}
參考:
1、https://www.apiref.com/cpp-zh/cpp/thread.html
2、https://en.cppreference.com/w/cpp/thread
3、書籍《c++服務器開發(fā)精髓》——張遠龍
你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧