頭文件 #include<future> 婆誓,在Linux下需要添加 -lpthread 參數
std::async
本質上是創(chuàng)建一個線程旦袋,使用傳遞的任務方法在線程中運行吸奴, 通過std::launch::async/deferred 來設置是否立即調用還是延遲調用
std::future
獲得任務結果, 使用future的get方法斩狱,獲得任務執(zhí)行的返回值网沾, 但是如果當前任務尚未執(zhí)行心软, 任務會觸發(fā)立即執(zhí)行壕吹, 并且堵塞當前線程,直到任務完成
方法
- get() //獲取任務返回結果删铃,該方法只能調用一次, 使用后futrue變得不確定
- wait() //等待任務完成
- wait_for(dur) //等待一定時間或運行完成
- wait_until(fp) //等待某一時刻或運行完成
- share() //生成一個shared_future耳贬,shared_futrue類型允許使用第二次, 并且使用獲得結果與第一次一樣猎唁,如果有一場咒劲,拋出的異常也是一樣的。
* 范例1
#include <iostream>
#include <future>
int main(int argc, char* args[])
{
//創(chuàng)建完成后線程實際上已經開始運行
std::future<int> ret = std::async([](){
std::cout << "Task Thread ID:" << std::this_thread::get_id() << std::endl;
//假設這里是一個很費時間的一個操作
return 0;
});
std::cout << "Main Thread ID:" << std::this_thread::get_id() << std::endl;
//如果當前任務未完成的話诫隅,主線程會堵塞腐魂,當然我們也可以把堵塞的任務傳遞給其他線程做
std::cout << "Ret:" << ret.get() << std::endl;
return 0;
}
* 范例2
多線程下的使用
#include <iostream>
#include <future>
//任務方法
void task(std::promise<int> &prom)
{
int ret;
//假設這里是一個很費時間的一個操作
ret = 4;
prom.set_value_at_thread_exit(ret);
}
//打印任務結果
void printRet(std::future<int> &future)
{
std::cout << "ret:" << future.get() << std::endl;
}
int main(int argc, char* args[])
{
std::promise<int> prom;
std::future<int> future = prom.get_future();
//創(chuàng)建線程執(zhí)行任務
std::thread t = std::thread(task, std::ref(prom));
//創(chuàng)建線程接受任務執(zhí)行結果
std::thread t2 = std::thread(printRet, std::ref(future));
//等待線程完成
t.join();
t2.join();
return 0;
}
* 范例3
參數傳遞
#include <iostream>
#include <future>
int sum(int a, int b)
{
return a + b;
}
int main(int argc, char* args[])
{
//創(chuàng)建完成后線程實際上已經開始運行,參數附加在末尾
std::future<int> ret = std::async(sum, 1, 2);
std::cout << "Main Thread ID:" << std::this_thread::get_id() << std::endl;
//如果當前任務未完成的話逐纬,主線程會堵塞蛔屹,當然我們也可以把堵塞的任務傳遞給其他線程做
std::cout << "Ret:" << ret.get() << std::endl;
return 0;
}
std::shared_future
使用與futrue相似。豁生,shared_futrue類型允許使用第二次判导, 并且使用獲得結果與第一次一樣嫉父,如果有一場,拋出的異常也是一樣的
std::shared_futrue f = std::async(task).share();
std::packaged_task(重點)
將任務打包眼刃, 好處是绕辖,可以手動觸發(fā)何時執(zhí)行任務
#include <iostream>
#include <future>
int sum(int a, int b)
{
std::cout << "Task Thread ID:" << std::this_thread::get_id() << std::endl;
return a + b;
}
int main(int argc, char* args[])
{
//對任務進行封裝
std::packaged_task<int(int, int)> task(sum);
//獲取future
std::future<int> future = task.get_future();
//直接出發(fā)任務task(1, 2),但是任務處于調用線程中
//移動到線程中執(zhí)行異步任務
std::thread t = std::thread(std::move(task), 1, 3);
std::cout << "Main Thread ID:" << std::this_thread::get_id() << std::endl;
std::cout << "Ret:" << future.get() << std::endl;
t.join();
return 0;
}
范例 4
使用wait_for 等待任務完成
#include <iostream>
#include <future>
double recursive(double a)
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
if ( a == 0)
{
return a;
}
return recursive(a - 1) + a;
}
int main()
{
std::packaged_task<double(double)> task(recursive);
std::future<double> future = task.get_future();
//移動到線程中處理
std::thread t = std::thread(std::move(task), 1000);
std::thread t2 = std::thread([](std::future<double>& future){
//等待線程完成執(zhí)行
while (future.wait_for(std::chrono::milliseconds(200)) == std::future_status::timeout)
{
std::cout << ".";
}
std::cout << "\n" << std::endl;
std::cout << "result:" << future.get() << std::endl;
}, std::ref(future));
t.join();
t2.join();
return 0;
}
范例 5
futrue共享狀態(tài)在get調用后就解除,下次調用會發(fā)生報錯擂红。 但是使用shared_future的時候仪际,get方法可調用多次,但是結果是一樣的
#include <iostream>
#include <future>
int do_work()
{
return 100;
}
int main()
{
std::future<int> future = std::async(do_work);
//獲取共享future
std::shared_future<int> shared_future = future.share();
//shared_future多次獲取結果
std::cout << "ret1:" << shared_future.get() << std::endl;
std::cout << "ret2:" << shared_future.get() << std::endl;
return 0;
}