1.std::future
std::future是一個模板類,可以從異步任務中獲取結果。將future對象與async,packaged_task對象進行綁定,調用get()函數來獲取結果。
2 .std::async
std::async 是c++11提供的一個創建異步任務的模板類,比thread類的功能更加全面。
async的三種啓動策略
(一)用std::launch::async啓動
#include<thread>
#include<stdio.h>
#include<future>
using namespace std;
int fun()
{
printf("%d\n", this_thread::get_id());
return 1;
}
int main()
{
printf("%d\n", this_thread::get_id());
future<int>fu = async(launch::async, fun);
int res = fu.get();
printf("%d", res);
}
輸出結果:
22436
10444
1
使用std::launch::async來創建async任務,會立即創建一個新線程。並且,當與之綁定的future對象調用get()函數時,如果任務沒有執行完畢,線程將阻塞,直到任務完畢。
(二)用std::launch::deferred啓動
#include<thread>
#include<stdio.h>
#include<future>
using namespace std;
int fun()
{
printf("%d\n", this_thread::get_id());
return 1;
}
int main()
{
printf("%d\n", this_thread::get_id());
future<int>fu = async(launch::deferred, fun);
int res = fu.get();
printf("%d", res);
}
輸出結果:
18672
18672
1
使用std::launch::deferred來創建async任務,會延遲調用這個任務,當與之綁定的future對象調用get()函數時,纔會在同一線程內執行此任務,如果不調用get()函數,這個任務就得不到執行。
(三)用std::launch::deferred|std::launch::deferred啓動
傳入std::launch::deferred|std::launch::deferred或者什麼也不加時,默認策略,由系統決定怎麼調用。
std::packaged_task
std::packaged_task 可以用來包裝可調用對象,由於thread類沒辦法通過join()函數獲取返回結果,所以可以通過與future對象綁定來獲取其作爲入口函數線程的返回結果。
#include<thread>
#include<stdio.h>
#include<future>
using namespace std;
int fun()
{
printf("%d\n", this_thread::get_id());
return 1;
}
int main()
{
printf("%d\n", this_thread::get_id());
packaged_task<int(void)>pk(fun);
future<int>fu = pk.get_future();
thread t(ref(pk));
t.join();
int res = fu.get();
printf("%d", res);
}
輸出結果:
4336
20100
1
使用thread來執行packaged_task可以創建一個新線程來執行這個任務。直接執行packaged_task對象也可以,但是不會在新的線程中執行。
#include<thread>
#include<stdio.h>
#include<future>
using namespace std;
int fun()
{
printf("%d\n", this_thread::get_id());
return 1;
}
int main()
{
printf("%d\n", this_thread::get_id());
packaged_task<int(void)>pk(fun);
future<int>fu = pk.get_future();
pk();
int res = fu.get();
printf("%d", res);
}
輸出結果:
5724
5724
1
std::promise
std::promise同樣是一個模板類,它提供了一種可以讓future對象即便不在同一個想成中,也可以異步的得到數據的方法。
#include<thread>
#include<stdio.h>
#include<future>
using namespace std;
int fun(promise<int>&pro)
{
printf("%d\n", this_thread::get_id());
pro.set_value(10);
return 1;
}
int main()
{
printf("%d\n", this_thread::get_id());
promise<int>pro;
future<int>fu = pro.get_future();
thread t(fun,ref(pro));
t.join();
int res = fu.get();
printf("%d", res);
}
輸出結果:
11892
20200
10