若是咱们想要异步获取线程处理结果,可使用future与async。async返回一个future对象,等待线程能够在future对象上获取异步线程的处理值。这里的异步,实际上主线程会阻塞。ios
【一】future的状态异步
future有三种状态:async
std::future_status::deferred; //表示异步线程还未启动 std::future_status::ready; //表示异步线程已经执行完毕,并已经将执行结果写入到future中 std::future_status::timeout; // 表示异步线程处理超时,并无将结果写入future中
【二】async是否启动线程函数
async是否启动异步线程,有async第一个参数决定,async接口定义以下:this
async(std::launch::async | std::launch::deferred, f, args...)
第一个参数表示异步线程启动的方式,有以下两种方式:spa
std::launch::async; // 表示表用async函数后,当即启动异步线程 std::launch::deferred; // 表示线程延迟启动,当调用future.get或者future.wait时,才会建立异步线程并启动
而async的默认方式见接口所示:线程
std::launch::async | std::launch::deferred // 表示是否启动线程由系统负载决定,若是系统负载太重,则可能不启动异步线程计算,则此时future的状态不会为ready, 通常状况下,这种默认设置够用了,可是若是须要必定以异步线程的方式执行,则显示修改启动方式为async
【三】future的四个方法code
future<int> fu; fu.get();
get声明以下:对象
返回future中存取的int值,get在拿到数据以前,会一直阻塞接口
fu.wait();
wait声明以下:
没有返回值,一直等待,直到future状态为ready为止
fu.wait_for();
wait_for声明以下:
等待必定的时间,返回值为future的状态,若是等待超时,返回time_out
fu.wait_until();就是等待到某个时间点,与wait_for相似。
【四】async采用默认启动参数
#include<iostream> #include<thread> #include<mutex> #include<condition_variable> #include<future> #include<chrono> using namespace std; int f(int i) { cout << "start" << endl; cout << "this thread id = " << std::this_thread::get_id() << endl; std::this_thread::sleep_for(2s); cout << "end" << endl; return i; } int main(int argc, int * argv[]) { future<int> fu = std::async(f, 8); cout << fu.get() << endl; cout << "main thread id = " << std::this_thread::get_id() << endl; cout << "main" << endl; system("pause"); }
结果以下:
能够看出,这里线程id不同。
【五】先wait,后get
#include<iostream> #include<thread> #include<mutex> #include<condition_variable> #include<future> #include<chrono> using namespace std; int f(int i) { cout << "start" << endl; cout << "this thread id = " << std::this_thread::get_id() << endl; std::this_thread::sleep_for(2s); cout << "end" << endl; return i; } int main(int argc, int * argv[]) { future<int> fu = std::async(f, 8); fu.wait(); cout << fu.get() << endl; cout << "main thread id = " << std::this_thread::get_id() << endl; cout << "main" << endl; system("pause"); }
结果以下:
【六】等待超时
#include<iostream> #include<thread> #include<mutex> #include<condition_variable> #include<future> #include<chrono> using namespace std; int f(int i) { cout << "start" << endl; cout << "this thread id = " << std::this_thread::get_id() << endl; std::this_thread::sleep_for(2s); cout << "end" << endl; return i; } int main(int argc, int * argv[]) { future<int> fu = std::async(f, 8); if (fu.wait_for(1s) == std::future_status::timeout) { cout << "time out" << endl; } else { cout << fu.get() << endl; } cout << "main thread id = " << std::this_thread::get_id() << endl; cout << "main" << endl; system("pause"); }
结果以下:
若是超时了还get,则会继续等待,直到future状态为ready,而后取出数据
#include<iostream> #include<thread> #include<mutex> #include<condition_variable> #include<future> #include<chrono> using namespace std; int f(int i) { cout << "start" << endl; cout << "this thread id = " << std::this_thread::get_id() << endl; std::this_thread::sleep_for(2s); cout << "end" << endl; return i; } int main(int argc, int * argv[]) { future<int> fu = std::async(f, 8); if (fu.wait_for(1s) == std::future_status::timeout) { cout << "time out" << endl; } // 超时继续get cout << fu.get() << endl; cout << "main thread id = " << std::this_thread::get_id() << endl; cout << "main" << endl; system("pause"); }
结果以下:
【七】设置aysnc启动方式
#include<iostream> #include<thread> #include<mutex> #include<condition_variable> #include<future> #include<chrono> using namespace std; int f(int i) { cout << "start" << endl; cout << "this thread id = " << std::this_thread::get_id() << endl; std::this_thread::sleep_for(2s); cout << "end" << endl; return i; } int main(int argc, int * argv[]) { // 设置启动方式为async future<int> fu = std::async(std::launch::async,f, 8); if (fu.wait_for(1s) == std::future_status::timeout) { cout << "time out" << endl; } cout << fu.get() << endl; cout << "main thread id = " << std::this_thread::get_id() << endl; cout << "main" << endl; system("pause"); }
结果以下: