Future
文章目录
- Future
- 获得方式
- 作用
- 原理
- 基本函数
- 基本用法
获得方式
- std::async 的返回值
- std::packaged_task 的消费方式
- std::promise 的消费方式
作用
- 查询 状态
- 等待 返回值
- 获取 返回值
- 以此配合完成线程同步
原理
- shared state 指针
基本函数
-
构造函数、析构函数和赋值操作等
// 构造函数,default 构造函数无 shared state 指针,此时 not valid,可移动赋值 // 综上,一共以上3种 + 移动赋值 四种构造 valid future 的方式 future() noexcept; future (const future&) = delete; future (future&& x) noexcept; // shared state 引用计数减一,若为0,shared state 析构 ~future(); // 赋值运算符,若之前valid,则shared state 引用计数减一,若为0,shared state 析构 future& operator= (future&& rhs) noexcept; future& operator= (const future&) = delete;
-
share 函数
- 返回 shared_future 对象,持有相同的 shared state 指针
-
与 future 的唯一区别是,可以多线程,多次get value
shared_future<T> share();
-
同步函数
// 是否与 shared state 关联 // default 构造 false // 三种构造 true // 成功 get value 后,且无重新赋值 false // 也就是 为 true 时,可以调用下面的函数,否则不可以 bool valid() const noexcept; // 当 shared state 为 ready 时,返回 value 或者 抛出异常 // 不 ready 时,阻塞线程 // 只可以调用一次,除非重新赋值 // 调用之后 valid 为 false,shared state 引用计数减一 R& future<R&>::get(); // when T is a reference type (R&) void future<void>::get(); // when T is void // 效果同 get(), 但是 不返回 value / exception 的效果 void wait() const; // 效果同 wait(), 但是 等一段时间(timeout_duration) 之后返回 // 当 deferred function 时,不阻塞 // future_status::ready、timeout、deferred template <class Rep, class Period> future_status wait_for (const chrono::duration<Rep,Period>& rel_time) const; // 效果同 wait(), 但是 等到(timeout_time) 之后返回 // 当 deferred function 时,不阻塞 // future_status::ready、timeout、deferred template <class Clock, class Duration> future_status wait_until (const chrono::time_point<Clock,Duration>& abs_time) const;
基本用法
-
检查 valid
-
根据需要调用同步函数
#include <iostream> #include <future> #include <thread> int main() { // packaged_task std::packaged_task<int()> task([]{ return 7; }); // wrap the function std::future<int> f1 = task.get_future(); // get a future std::thread t(std::move(task)); // launch on a thread // async() std::future<int> f2 = std::async(std::launch::async, []{ return 8; }); // promise std::promise<int> p; std::future<int> f3 = p.get_future(); std::thread( [&p]{ p.set_value_at_thread_exit(9); }).detach(); // wait + get if (f1.valid()) { f1.wait(); std::cout << "f1 get: " << f1.get() << std::endl; } // wait_for + get if (f2.valid()) { auto s2 = f2.wait_for(std::chrono::seconds(1)); if (s2 == std::future_status::ready) std::cout << "f2 get: " << f2.get() << std::endl; } // wait_until + get if (f3.valid()) { auto s3 = f3.wait_until(std::chrono::system_clock::now() + std::chrono::seconds(2)); if (s3 == std::future_status::ready) std::cout << "f3 get: " << f3.get() << std::endl; } t.join(); }