C++11异步操作
C++ 11 提供了异步操作相关的类,主要有std::future std::promise std::package_task
std::future 作为异步结果的传输通道,获取线程函数的返回值;
std::promise 用来包装一个值,将数据和std::future 绑定;
std::package 用来包装一个对象,将数据和future 绑定起来,以方便异步调用;
std::future
future 提供了异步查询的通道,我们可以用同步等待的方式来获取结果,可以通过查询future 的状态(future_status )来获取异步操作的结果
enum class future_status {
ready,
timeout,
deferred
};
我们可以不断查询future 的状态,并比对,直到任务完成为止
std::promise
std::promise 将数据和future 绑定,为获取线程中的某个值提供便利
- 在线程函数中为
promise 赋值 - 在线程函数执行完毕后就可以通过
promise 的future 获取值
示例:
#include<iostream>
#include <string>
#include <tuple>
#include <mutex>
#include <thread>
#include <list>
#include <condition_variable>
#include <future>
using namespace std;
std::promise<int> pr;
void set_value(int i)
{
std::this_thread::sleep_for(std::chrono::seconds(3));
pr.set_value_at_thread_exit(i);
}
int main()
{
std::thread t1(set_value, 90);
t1.join();
std::future<int> f = pr.get_future();
cout << f.get() << endl;
}
std::package_task
std::package_task 包装了一个可调用对象的包装类(function ,lambda function ,bind expression…)
将函数和future 绑定起来,以便异步调用
示例:
#include<iostream>
#include <string>
#include <tuple>
#include <mutex>
#include <thread>
#include <list>
#include <condition_variable>
#include <future>
#include <functional>
using namespace std;
int return_value(int i )
{
cout << i << endl;
return i * 10;
}
int main()
{
std::packaged_task<int(int)> task(return_value);
std::future<int> f = task.get_future();
std::thread t(std::ref(task),4);
t.join();
int result = f.get();
cout << result << endl;
}
std::future``std::promise``std::package_task 之间区别
std::future 提供了一个访问异步操作结果的机制,它和线程是一个级别的,属于低层次的对象。在std::future 之上的高一层是std:packaged_task 和std::promise ,它们内部都有future 以便访问异步操作结果,std::packaged_task 包装的是一个异步操作,而std:;promise 包装的是一个值,都是为了方便异步操作,因为有时需要获取线程中的某个值,这时就用std:promise ,而有时需要获一个异步操作的返回值,这时就用std:packaged_task 。那么std:promise 和std:packaged_task 之间又是什么关系呢?可以将一个异步操作的结果保存到std::promise 中。future 被promise 和package_task 用来作为异步操作或者异步结果的连接通道,用std::future 和std:.shared_future 来获取异步调用的结果。future 是不可拷贝的,只能移动,shared_future 是可以拷贝的,当需要将future 放到容器中则需要用shared_future , package_task 和 shared_future 的基本用法如下:
#include<iostream>
#include <string>
#include <tuple>
#include <mutex>
#include <thread>
#include <list>
#include <condition_variable>
#include <future>
#include <functional>
using namespace std;
int func(int x)
{
return x + 1;
}
int main()
{
std::packaged_task<int(int)> task(func);
std::future<int> fut = task.get_future();
std::thread(std::move(task), 2).detach();
int value = fut.get();
cout << value << endl;
vector<std::shared_future<int >> v;
std::shared_future<int> f = std::async(std::launch::async, [](int a, int b) {return a + b; }, 2, 3);
v.push_back(f);
std::cout << v[0].get() << endl;
}
有点绕啊…
std::async
std::async 可以直接用来创建异步的task,异步操作结果也保存在future 中,获取结果时future.get() ,
如果不关注异步任务的结果,只是简单地等待任务完成,则调用future.wait() 方法
第一个参数f 是创建线程的策略
std::launch::async :在调用async 时就开始创建线程std::launch::deferred :延迟方式创建线程.调用async 时不创建线程,调用future 函数的get() 或者wait() 时才创建
|