c++ 學習之 多線程(九)async,future,packaged_task,promise

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章