C++ future async promise 用法详解 - shared_future
shared_future
获得方式
- 只能由 future 得到
作用
- 同 future
区别
- 可以多线程、多次访问 shared state
原理
- shared state 指针 + 引用计数
基本函数
-
构造函数、析构函数和赋值操作等
// valid 情况 1 :false,2 :同参数,且参数 valid 情况不变,3、4 :同参数,且参数 valid 变为 false shared_future() noexcept; shared_future (const shared_future& x); shared_future (shared_future&& x) noexcept; shared_future (future<T>&& x) noexcept; // shared state 引用计数减一,若为0,shared state 析构 ~shared_future(); // 若之前 valid,将之前 shared state 引用计数减一,若为0,shared state 析构 // 赋值之后 引用计数 +1, valid 同参数,1 : 参数 valid 不变,2 :参数 valid 变为 false shared_future& operator= (shared_future&& rhs) noexcept; shared_future& operator= (const shared_future& rhs);
-
同步函数
- 效果跟 future 完全相同
- 除了 shared state 可以被多个 shared future 共享,并用引用计数维护
- 可以 多对象、 多线程、 多次调用
// 是否与 shared state 关联 // default 构造 false bool valid() const noexcept; // 当 shared state 为 ready 时,返回 value 或者 抛出异常 // 不 ready 时,阻塞线程 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 <chrono> #include <iostream> #include <future> #include <vector> #include <thread> int fib(int n) { if (n < 3) return 1; else return fib(n-1) + fib(n-2); } int main() { // future std::future<int> f0 = std::async(std::launch::async, [](){ return fib(1 << 5); }); std::cout << "f0: " << f0.valid() << '\n'; // shared_future std::shared_future<int> f1(std::move(f0)); std::cout << "f0: " << f0.valid() << '\n'; std::cout << "f1: " << f1.valid() << '\n'; std::shared_future<int> f2 = f1; std::cout << "f1: " << f1.valid() << '\n'; std::cout << "f2: " << f2.valid() << '\n'; std::shared_future<int> f3(std::move(f1)); std::cout << "f1: " << f1.valid() << '\n'; std::cout << "f2: " << f2.valid() << '\n'; std::cout << "f3: " << f2.valid() << '\n'; // future f0 = std::async(std::launch::async, [](){ return fib((1 << 5) + (1 << 3)); }); std::cout << "f0: " << f0.valid() << '\n'; // shared_future f1 = f0.share(); std::cout << "f0: " << f0.valid() << '\n'; std::cout << "f1: " << f1.valid() << '\n'; std::cout << "f2: " << f2.valid() << '\n'; std::cout << "f3: " << f2.valid() << '\n'; std::cout << "f1: " << f1.get() << '\n'; std::cout << "f2: " << f2.get() << '\n'; std::cout << "f2: " << f3.get() << '\n'; std::vector<std::thread> ts; for (size_t i = 0; i < 10; i++) ts.emplace_back(std::move(std::thread([&](){ std::cout << "f1: " << f1.valid() << " " << f1.get() << '\n'; std::cout << "f2: " << f2.valid() << " " << f2.get() << '\n'; std::cout << "f3: " << f2.valid() << " " << f2.get() << '\n'; }))); for (auto& t : ts) t.join(); return 0; }
未完待续
- 相关bug
- 性能测试 & 最佳场景