c++11总结06——异步操作类

c++11提供了异步操作类,主要包括std::future、std::promise和std::package_task。另外还有更高层次的异步操作std::async。

std::future

thread库提供了std::future用来访问异步操作的结果。future,顾名思义,代表的是未来的一个期待值,future提供了获取异步操作结果的通道。

future_status有3种状态,如下所示:

1)Deferred:异步操作还未开始;

2)Ready:异步操作已经完成;

3)Timeout:异步操作超时;

获取future结果有3种方式:

1)get:等待异步操作结束并返回结果;

2)wait:等待异步操作完成,无返回值;

3)wait_for:超时等待返回结果;

例如:

std::future_status status;
status = future.wait_for(std::chrono::seconds(1));

std::promise

std::promise将数据与future绑定起来,为获取线程函数中的某个值提供便利,在线程函数中为外面传进来的promise赋值,在线程函数执行完成后可以通过promise的future获取该值了。

例如:

std::promise<int> ptr;
std::thread t([](std::promise<int>& p) {
	p.set_value_at_thread_exit(9);
}, std::ref(ptr));

std::future<int> f = ptr.get_future();
auto r = f.get();

std::package_task

std::package_task包装了一个可调用的包装类(类似于function、lambda expression、bind expression和another function object),将函数和future绑定起来,便于异步调用。

例如:

std::packaged_task<int()> task([]() { return 2; });
std::thread t1(std::ref(task));
std::future<int> f1 = task.get_future();
auto r1 = f1.get();

三者联系

std::package_task和std::promise内部都有future以便访问异步结果,可以这样理解,std::package_task包装的是一个函数,std::promise包装的是一个值。

future被promise和package_task用来作为异步操作或者异步结果的连接通道,用std::future和std::shared_future来获取异步调用结果。future是不可拷贝的,只能移动,shared_future是可以拷贝的,当需要将future放到容器中则需要使用shared_future。

示例代码

#include <iostream>
#include <utility>
#include <future>
#include <thread>
#include <vector>
using namespace std;

int foo(int i)
{
	return i + 1;
}

int main()
{
	std::packaged_task<int(int)> task(foo);    //将函数与future绑定起来
	std::future<int> f0 = task.get_future();    //获取future

	std::thread(std::move(task), 2).detach();  

	int iValue = f0.get();
	cout << "the result is " << iValue << endl;

	std::vector<std::shared_future<int>> vec;
	std::shared_future<int> f1 = std::async(std::launch::async, [](int m, int n) {
		return m + n; 
	}, 1, 2);
	vec.push_back(f1);
	cout << "the shared_future is " << vec[0].get() << endl;

	system("pause");
    return 0;
}

运行结果:

the result is 3

the shared_future is 3

注意:

std::vector<std::shared_future<int>> vec;
auto f1 = std::async(std::launch::async, [](int m, int n) {
        return m + n; 
}, 1, 2);

vec.push_back(f1);

此处如写auto让其自行推导类型,在vs2015编译会报这种错误:

无法将参数 1 从“std::future<_ret>”转换为“std::shared_future<_ty> &&

async

如上例所示,std:;async是更高层次的异步操作,可以用来直接创建异步的task,异步任务返回的结果保存在future中。

std::async的原型:

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

1)std::launch::async:在调用async时就开始创建线程

2) std::launch::deferred:延迟加载方式创建线程。调用async时不创建线程,直到调用了future的get或者wait时才创建线程。

f代表线程函数,args...代表线程函数的参数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值