异步操作的主要目的是让调用方法的主线程不需要同步等待调用函数,从而可以让主线程继续执行它下面的代码。因此异步操作无须额外的线程负担,使用回调的方式进行处理。在设计良好的情况下,处理函数可以不必或者减少使用共享变量,减少了死锁的可能。当需要执行I/O操作时,使用异步操作比使用线程+同步 I/O操作更合适。
异步和多线程并不是一个同等关系,异步是目的,多线程是实现异步的一个手段。实现异步可以采用多线程或交给另外的进程来处理。
C++11中的异步操作主要有std::future、std::async、std::promise、std::packaged_task。
1、std::future
future对象是std::async、std::promise、std::packaged_task的底层对象,用来传递其他线程中操作的数据结果。
函数原型:
#include <future>
template< class T > class future;
template< class T > class future<T&>;
template<> class future<void>;
成员函数: |
|
构造 future 对象 (公开成员函数) |
|
析构 future 对象 (公开成员函数) |
|
移动future对象 (公开成员函数) |
|
从 *this 转移共享状态给 shared_future 并返回它 (公开成员函数) |
|
获取结果: |
|
返回结果 (公开成员函数) |
|
状态: |
|
检查 future 是否拥有共享状态(公开成员函数) |
|
等待结果变得可用(公开成员函数) |
|
等待结果,如果在指定的超时间隔后仍然无法得到结果,则返回。 (公开成员函数) |
|
等待结果,如果在已经到达指定的时间点时仍然无法得到结果,则返回。 |
类模板std::future提供访问异步操作结果的机制:
(1)通过 std::promise、std::packaged_task和std::async创建的异步操作能提供一个 std::future 对象给该异步操作的创建者。
(2)异步操作的创建者能用各种方法查询、等待或从 std::future 提取值。若异步操作仍未提供值,则这些方法可能阻塞。
(3)异步操作准备好发送结果给创建者时,它能通过修改链接到创建者的 std::future 的共享状态(例如 std::promise::set_value )进行。
注:
- std::future 所引用的共享状态不与另一异步返回对象共享(与 std::shared_future 相反)。
- std::asyanc是std::future的高级封装