【C++多线程系列】【九】future与async

若是咱们想要异步获取线程处理结果,可使用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");
}

结果以下:

相关文章
相关标签/搜索