C++11多线程之async

什么是std::async?

std::async 是一个接受回调(函数对象or函数本体)作为参数的函数模板,可以同步或异步执行

std::async特点分析

std::async 定位于头文件

template< class Function, class... Args >
std::future<std::invoke_result_t<std::decay_t<Function>, std::decay_t<Args>...>>
    async( std::launch policy, Function&& fn, Args&&... args );

函数模板 async 异步地运行函数 fn,最终返回保有该函数调用结果的std::future。

  • std::launch policy它控制std::async的异步行为,我们可以用三种不同的启动策略来创建std::async;
    • std::launch::async 传递的可调用对象异步执行;
    • std::launch::deferred 传递的可调用对象同步执行;
    • std::launch::async | std::launch::deferred 可以异步或是同步,取决于操作系统,我们无法控制;
    • 如果未指定,默认运行策略使用std::launch::async | std::launch::deferred,异步运行或不运行,这取决于系统的负载,但我们无法控制它;
  • fn:函数,函数对象、lambda等;
  • args 函数fn的调用参数;
代码释义
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>
using namespace std;
int AddFunc(int a, int b, int sleep)
{
	cout << "function thread id=" << std::this_thread::get_id() << endl;
	cout << __FUNCTION__ << " sleep begin " << std::this_thread::get_id() << endl;
	this_thread::sleep_for(chrono::seconds(sleep));
	cout << __FUNCTION__ << " sleep end " << std::this_thread::get_id() << endl;
	auto ret = a + b;
	cout << "thread id=" << std::this_thread::get_id() << " ret = " << ret << endl;
	return ret;
}

void TestBindRetFuture()
{
	{
		//当async返回值无绑定的future,直到执行完毕才开始新的async
		async(launch::async, AddFunc, 1, 2, 5);
		async(launch::async, AddFunc, 3, 4, 2);
		cout << "==========================================================" << endl;
	}
	{
		//绑定返回值,则多个async同时异步执行
		auto ret_future1 = async(launch::async, AddFunc, 1, 2, 5);
		auto ret_future2 = async(launch::async, AddFunc, 3, 4, 2);
		cout << "==========================================================" << endl;
	}
}

void TestLaunchPolicy()
{
	{
		//异步函数
		future<int> ret_future1 = async(launch::async, AddFunc, 1, 2, 2);
		cout << "main create async async" << endl;
		this_thread::sleep_for(chrono::seconds(1));
		cout << "main sleep_for end" << endl;
		int ret = ret_future1.get();
		cout << "async ret_future1=" << ret << endl;
		cout << "==========================================================" << endl;
	}
	{
		//同步函数,函数会在future.get()时才执行
		future<int> ret_future1 = async(launch::deferred, AddFunc, 1, 2, 2);
		cout << "main create async deferred" << endl;
		this_thread::sleep_for(chrono::seconds(1));
		cout << "main sleep_for end" << endl;
		int ret = ret_future1.get();
		cout << "deferred ret_future1=" << ret << endl;
		cout << "==========================================================" << endl;
	}
}
void TestClassFunc()
{
	class TmpClass {
	public:
		TmpClass(){};
		~TmpClass(){};
		int RetFuncAdd(int a, int b, int sleep = 0)
		{
			cout << "RetFuncAdd thread id=" << std::this_thread::get_id() << endl;
			cout << __FUNCTION__ << " sleep begin " << std::this_thread::get_id() << endl;
			this_thread::sleep_for(chrono::seconds(sleep));
			cout << __FUNCTION__ << " sleep end " << std::this_thread::get_id() << endl;
			obj_ret = a + b;
			cout << "thread id=" << std::this_thread::get_id() << " ret = " << obj_ret << endl;
			return obj_ret;
		}
		int GetObjRet() { return obj_ret; };

	private:
		int obj_ret;
	};

	TmpClass test_obj;
	//异步函数
	future<int> ret_future1 = async(launch::async, &TmpClass::RetFuncAdd, &test_obj,  1, 2, 2);
	cout << "main create async async" << endl;
	this_thread::sleep_for(chrono::seconds(1));
	cout << "main sleep_for end" << endl;
	int ret = ret_future1.get();
	cout << "async ret_future1=" << ret << endl;
	cout << "TmpClass obj_ret=" << test_obj.GetObjRet() << endl;
	cout << "==========================================================" << endl;
}
int main()
{
	cout << "main thread id=" << std::this_thread::get_id() << endl;
	//TestBindRetFuture();
	//TestLaunchPolicy();
	TestClassFunc();
	return 0;
}
std::async注意点

若从 std::async 获得的 std::future 未被移动或绑定到引用,则在完整表达式的末尾, std::future 的析构函数将阻塞直至异步计算完成,简化代码释义如下:

std::async(std::launch::async, []{ func1(); }); // 临时量的析构函数等待 func1(),返回值未绑定
std::async(std::launch::async, []{ func2(); }); // func1() 完成前不开始
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值