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

如果我们想要异步获取线程处理结果,可以使用future与async。async返回一个future对象,等待线程可以在future对象上获取异步线程的处理值。这里的异步,实际上主线程会阻塞。

【一】future的状态

future有三种状态:

std::future_status::deferred;  //表示异步线程还未启动
std::future_status::ready;     //表示异步线程已经执行完毕,并已经将执行结果写入到future中
std::future_status::timeout;   // 表示异步线程处理超时,并没有将结果写入future中

【二】async是否启动线程

async是否启动异步线程,有async第一个参数决定,async接口定义如下:

async(std::launch::async | std::launch::deferred, f, args...)

第一个参数表示异步线程启动的方式,有如下两种方式:

std::launch::async; // 表示表用async函数后,立即启动异步线程
std::launch::deferred; // 表示线程延迟启动,当调用future.get或者future.wait时,才会创建异步线程并启动

而async的默认方式见接口所示:

std::launch::async | std::launch::deferred  // 表示是否启动线程由系统负载决定,如果系统负载过重,则可能不启动异步线程计算,则此时future的状态不会为ready, 一般情况下,这种默认设置够用了,但是如果需要一定以异步线程的方式执行,则显示修改启动方式为async

【三】future的四个方法

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");
}

结果如下:

猜你喜欢

转载自my.oschina.net/u/3800567/blog/1806504