异步线程
异步线程的引入解决了线程有依赖关系的情景。c++11提供了std::async,std::packaged_task,std::promise,三种方法。
1.std::async
std::async启动一个异步的任务,并返回一个std::future对象,可以通过future对象获取到异步任务的执行结果。
async的第一个参数的选择:
std::launch::deferred(默认值):表示future对象调用wait或get才执行任务,不会创建子线程;
std::launch::async:表示future对象不调用wait或get就会执行任务,并创建子线程;
#include <iostream>
#include <thread>
#include <future>
using namespace std;
int task(int age)
{
cout << "sub thread id:" << std::this_thread::get_id()<< endl;
return age;
}
int main()
{
cout << "main thread id:" << std::this_thread::get_id()<< endl;
std::future<int> futureObj = std::async(std::launch::async, task, 100);
std::this_thread::sleep_for(std::chrono::seconds(2)); //测试launch策略
cout << "main wait 2 seconds ..." << endl;
cout << futureObj.get() << endl;
return 0;
}
//打印结果
root@epc:/home/share/test# ./test
main thread id:140009135093568
sub thread id:140009117652736
main wait 2 seconds ...
100
root@epc:/home/share/test#
2.std::packaged_task
std::packaged_task顾名思义,它将任务(包括函数和lambda表达式等)封装起来,作为线程的入口函数。它的成员函数get_future()返回一个std::future对象用来获取线程执行返回结果。
//包装task作为thread入口
#include <iostream>
#include <thread>
#include <future>
using namespace std;
int task(int age)
{
cout << "sub thread id:" << std::this_thread::get_id()<< endl;
return age;
}
int main()
{
cout << "main thread id:" << std::this_thread::get_id()<< endl;
std::packaged_task<int(int)> myPackage(task); //把task函数封装起来;
std::thread myTread(std::ref(myPackage), 100);
myTread.join();
std::future<int> myFuture = myPackage.get_future();
cout << myFuture.get() << endl;
return 0;
}
//打印结果
root@epc:/home/share/test# ./test
main thread id:139797674174272
sub thread id:139797656733440
100
root@epc:/home/share/test#
3.std::promise
std::promise的set_value函数能够获取线程执行结果,它的成员函数get_future()返回一个std::future对象用来获取线程执行返回结果。
#include <iostream>
#include <thread>
#include <future>
using namespace std;
int task(std::promise<int> &myPromise, int age)
{
cout << "sub thread id:" << std::this_thread::get_id()<< endl;
myPromise.set_value(age); //std::promise的set_value函数能够获取线程执行结果
return age;
}
int main()
{
cout << "main thread id:" << std::this_thread::get_id()<< endl;
std::promise<int> myPromise;
std::thread myTread(task, std::ref(myPromise), 100);
myTread.join();
std::future<int> myFuture = myPromise.get_future();
cout << myFuture.get() << endl;
return 0;
}