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
    • 性能测试 & 最佳场景
posted @ 2021-05-13 23:54  Jamgun  阅读(172)  评论(0编辑  收藏  举报