C++ future async promise 用法详解 - promise

背景

  • 不想利用async提供的线程模型
  • 还想方便的获取线程运行结果

原理

  • 生产者 - 消费者模型

基本函数

  • 生产函数,分两步

    • 设置value或者exception
    • 设置shared state
    template <class R&>
    // 设置value或者exception后,立即将shared state设置为ready
    void set_value (R& val);
    void set_exception (exception_ptr p);
    // 设置value或者exception后,在当前线程退出后才把shared state设置为ready
    void set_value_at_thread_exit (R& val);
    void set_exception_at_thread_exit (exception_ptr p);
    
  • 消费函数

    获取future,负责保存shared state和value/exception

    template <class T>
    future<T> get_future();
    
  • 其他函数

    // 构造函数
    promise();
    promise (const promise&) = delete;
    promise (promise&& x) noexcept;
    // 只可用移动赋值运算
    promise& operator= (promise&& rhs) noexcept;
    promise& operator= (const promise&) = delete;
    // swap 函数
    void swap (promise& x) noexcept;
    template <class T>
    void swap (promise<T>& x, promise<T>& y) noexcept;
    

基本用法

  • 生产者push执行结果,消费者pop执行结果

  • 生产者push状态,消费者pop状态

  • 单生产,单消费不会有异常;多生产/多消费需要处理异常状态

  • 支持线程池的使用

    #include <vector>
    #include <thread>
    #include <future>
    #include <numeric>
    #include <iostream>
    #include <chrono>
    
    // value 通信
    void accumulate(std::vector<int>::iterator first,
                    std::vector<int>::iterator last,
                    std::promise<int> accumulate_promise) {
        int sum = std::accumulate(first, last, 0);
        accumulate_promise.set_value(sum);  // 生产一次
    }
    // state 通信
    void do_work(std::promise<void> barrier) {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        barrier.set_value(); // 生产一次
    }
    
    int main() {
        // value 通信
        std::vector<int> numbers = { 1, 2, 3, 4, 5, 6 };
        std::promise<int> accumulate_promise; // 构造
        std::future<int> accumulate_future = accumulate_promise.get_future(); // 获取消费者
        std::thread work_thread(accumulate, numbers.begin(), numbers.end(),
                                std::move(accumulate_promise));    // 生产线程
        std::cout << "result=" << accumulate_future.get() << '\n'; // 消费一次
        work_thread.join();  // wait for thread completion
    
        // state 通信
        std::promise<void> barrier; // 构造
        std::future<void> barrier_future = barrier.get_future();  // 获取消费者
        std::thread new_work_thread(do_work, std::move(barrier)); // 生产线程
        barrier_future.wait();   // 消费一次
        new_work_thread.join();  // wait for thread completion
    }
    
posted @ 2021-05-13 23:49  Jamgun  阅读(293)  评论(0编辑  收藏  举报