• c++11 多线程支持 (std::shared_future)


    定义于头文件 
    1. template< class T > class shared_future; (1) (C++11 起)
    2. template< class T > class shared_future<T&>; (2) (C++11 起)
    3. template<> class shared_future<void>; (3) (C++11 起)

    类模板 std::shared_future 提供访问异步操作结果的机制,类似 std::future ,除了允许多个线程等候同一共享状态。不同于仅可移动的 std::future (故只有一个实例能指代任何特定的异步结果),std::shared_future 可复制而且多个 shared_future 对象能指代同一共享状态。

    若每个线程通过其自身的 shared_future 对象副本访问,则从多个线程访问同一共享状态是安全的。

    构造函数

    1. shared_future() noexcept; (1) (C++11 起)
    2. shared_future( const shared_future& other ); (2) (C++11 起) (C++17 前)
    3. shared_future( const shared_future& other ) noexcept; (C++17 起)
    4. shared_future( std::future<T>&& other ) noexcept; (3) (C++11 起)
    5. shared_future( shared_future&& other ) noexcept; (4) (C++11 起)

    构造新的 shared_future

    1) 默认构造函数。构造空的 shared_future ,它不指代共享状态,即 valid() == false 。

    2) 构造与 other 指代同一共享状态的 shared_future ,若有共享状态。

    3-4) 转移 other 所保有的共享状态给 *this 。构造后, other.valid() == false 且 this->valid() 返回与 other.valid() 在构造前会返回者相同的值。

    参数

    other-用以初始化的另一 future 对象

     

    析构函数

    std::shared_future<T>::~shared_future
    ~shared_future();        (C++11 起) 

    若 *this 是指代共享状态的最后一个对象,则销毁共享状态。否则不做任何事。

    赋值内容

    std::shared_future<T>::operator=
    1. shared_future& operator=( const shared_future& other ); (C++11 起)(C++17 前)
    2. shared_future& operator=( const shared_future& other ) noexcept; (C++17 起)
    3. shared_future& operator=( shared_future&& other ) noexcept; (2) (C++11 起)

    shared_future& operator=( shared_future&& other ) noexcept;

    (2)(C++11 起)

    赋值另一 shared_future 的内容。

    1) 释放任何共享状态并赋值 other 的内容给 *this 。赋值后, this->valid() == other.valid() 。

    2) 释放任何共享状态并移动赋值 other 的内容给 *this 。赋值后, other.valid() == false 且 this->valid() 将产生与 other.valid() 在赋值前相同的值。

    参数

    other-将转移状态给 *this 的 std::shared_future

    返回值

    *this

    检查 future 是否拥有共享状态

    std::shared_future<T>::valid
    bool valid() const noexcept;    (C++11 起) 

    检查期货是否指代共享状态。

    这是非默认构造或被移动的期货的仅有情况。不同于 std::future ,调用 get() 时不非法化 std::shared_future 的共享状态。

    若在不指代共享状态的 shared_future 上调用任何析构函数、复制赋值运算符、移动赋值运算符或 valid 以外的成员函数,则行为未定义(尽管鼓励实现在此情况下抛出指示 no_state 的 std::future_error )。从 valid()false 的 shared_future 对象移动或复制是合法的。

    参数

    (无)

    返回值

    若 *this 指代共享状态则为 true ,否则为 false 。

    等待结果变得可用

    std::shared_future<T>::wait
    void wait() const;             (C++11 起) 

    阻塞直至结果变得可用。调用后 valid() == true 。

    若调用此函数前 valid()== false 则行为未定义。

    参数

    (无)

    返回值

    (无)

    异常

    (无)

    注意

    鼓励实现检测调用前 valid == false 的情况并抛出以 std::future_errc::no_state 为 error_condition 的 std::future_error 。

    在同一 std::shared_future 上从多个线程调调用 wait 不安全;有意图的使用是令每个等待于同一共享状态上的线程拥有一个 std::shared_future 的副本。

    调用示例

    1. #include <iostream>
    2. #include <future>
    3. #include <thread>
    4. int fib(int n)
    5. {
    6. if (n < 3)
    7. {
    8. return 1;
    9. }
    10. else
    11. {
    12. return fib(n - 1) + fib(n - 2);
    13. }
    14. }
    15. int main()
    16. {
    17. std::shared_future<int> f1 = std::async(std::launch::async, []()
    18. {
    19. return fib(20);
    20. });
    21. std::shared_future<int> f2 = std::async(std::launch::async, []()
    22. {
    23. return fib(25);
    24. });
    25. std::cout << "waiting...\n";
    26. f1.wait();
    27. f2.wait();
    28. std::cout << "f1: " << f1.get() << '\n';
    29. std::cout << "f2: " << f2.get() << '\n';
    30. }

    输出

     

    等待结果,如果在指定的超时间隔后仍然无法得到结果,则返回。

    std::shared_future<T>::wait_for
    1. template< class Rep, class Period >
    2. std::future_status wait_for(
    3. const std::chrono::duration<Rep,Period>& timeout_duration ) const;(C++11 起)

    等待结果变得可用。阻塞直至经过指定的 timeout_duration ,或结果变为可用,两者的先到来者。返回值鉴别结果的状态。

    此函数可能由于调度或资源争议延迟而阻塞长于 timeout_duration

    推荐标准库用稳定时钟度量时长。若实现用系统时钟代替,则等待时间可能也对时钟调整敏感。

    若调用此函数前 valid()== false 则行为未定义。

    参数

    timeout_duration-要阻塞的最大时长

    返回值

    常量解释
    future_status::deferred要计算结果的函数仍未启动
    future_status::ready结果就绪
    future_status::timeout已经过时限

    异常

    时钟、时间点或时长在执行中可能抛的任何异常(标准库提供的时钟、时间点和时长决不抛出)。

    注意

    鼓励实现在调用前检测 valid == false 的情况并抛出以 future_errc::no_state 为 error_condition 的 future_error 。

    等待结果,如果在已经到达指定的时间点时仍然无法得到结果,则返回。

    std::shared_future<T>::wait_until
    1. template< class Clock, class Duration >
    2. std::future_status wait_until(
    3. const std::chrono::time_point<Clock,Duration>& timeout_time ) const; (C++11 起)

    wait_until 等待结果变为可用。它阻塞直至抵达指定的 timeout_time ,或结果变为可用,两者的先到来者。返回值指示 wait_until 为何返回。

    若调用此函数前 valid()== false 则行为未定义。

    参数

    timeout_time-要阻塞到的最大时间点

    返回值

    常量解释
    future_status::deferred要计算结果的函数仍未启动
    future_status::ready结果就绪
    future_status::timeout已经过时限

    异常

    时钟、时间点或时长在执行中可能抛的任何异常(标准库提供的时钟、时间点和时长决不抛出)。

    注意

    鼓励实现在调用前检测 valid == false 的情况并抛出以 future_errc::no_state 为 error_condition 的 future_error 。

    使用倾向 timeout_time 的时钟,不要求是单调时钟。若不连续地调节时钟,则不对此函数的行为保证,但既存实现将 timeout_timeClock 转换到 std::chrono::system_clock ,并委托 POSIX pthread_cond_timedwait 以令等待忠实于系统时钟,但非用户提供 Clock 的调节。任何情况下,由于调度或资源争议延迟,函数可能等待长于抵达 timeout_time

    返回结果

    std::shared_future<T>::get
    1. const T& get() const; (1) (仅为泛型 shared_future 模板的成员) (C++11 起)
    2. T& get() const; (2) (仅为 shared_future<T&> 模板特化的成员)(C++11 起)
    3. void get() const; (3) (仅为 shared_future<void> 模板特化的成员)(C++11 起)

    get 方法等待直至 shared_future 拥有合法结果并(依赖于使用哪个模板)获取它。它等效地调用 wait() 等待结果。

    泛型模板和二个模板特化各含单个 get 版本。 get 的三个版本仅在返回类型有别。

    若调用此函数前 valid() 为 false 则行为未定义。

    参数

    (无)

    返回值

    1) 到存储于共享状态的值的 const 引用。销毁共享状态后,通过此引用访问值是未定义行为。

    2) 存储于共享状态的值的引用。

    3) 无。

    异常

    若 future 所引用的共享状态中存储异常(例如,通过调用 std::promise::set_exception() ),则抛出该异常。

    注意

    鼓励实现在调用前检测 valid() 为 false 的情况,并抛出以 std::future_errc::no_state 为 error_condition 的 std::future_error 。

    调用示例

    1. #include <iostream>
    2. #include <future>
    3. #include <chrono>
    4. int main()
    5. {
    6. std::promise<void> ready_promise, t1_ready_promise, t2_ready_promise;
    7. std::shared_future<void> ready_future(ready_promise.get_future());
    8. std::chrono::time_point<std::chrono::high_resolution_clock> start;
    9. auto fun1 = [&, ready_future]() -> std::chrono::duration<double, std::milli>
    10. {
    11. t1_ready_promise.set_value();
    12. ready_future.wait(); // 等待来自 main() 的信号
    13. return std::chrono::high_resolution_clock::now() - start;
    14. };
    15. auto fun2 = [&, ready_future]() -> std::chrono::duration<double, std::milli>
    16. {
    17. t2_ready_promise.set_value();
    18. ready_future.wait(); // 等待来自 main() 的信号
    19. return std::chrono::high_resolution_clock::now() - start;
    20. };
    21. auto result1 = std::async(std::launch::async, fun1);
    22. auto result2 = std::async(std::launch::async, fun2);
    23. // 等待线程变为就绪
    24. t1_ready_promise.get_future().wait();
    25. t2_ready_promise.get_future().wait();
    26. // 线程已就绪,开始时钟
    27. start = std::chrono::high_resolution_clock::now();
    28. // 向线程发信使之运行
    29. ready_promise.set_value();
    30. std::cout << "Thread 1 received the signal "
    31. << result1.get().count() << " ms after start\n"
    32. << "Thread 2 received the signal "
    33. << result2.get().count() << " ms after start\n";
    34. }

    输出

     

  • 相关阅读:
    MYSQL-索引
    guava之RateLimiter
    网络安全工程师需要学什么?零基础怎么从入门到精通,看这一篇就够了
    Python中向量的表示
    webpack--打包出口(output)
    php+html+js+ajax实现文件上传
    智哪儿线下活动来啦 ~这次我想和你聊聊「AI营销」的生意经
    vue3后台管理框架之Mock开发
    vue-cli3.0--多环境构建(模式和环境变量)--使用/实例
    不允许你还不会OSS文件操作,看完一篇就够了
  • 原文地址:https://blog.csdn.net/qq_40788199/article/details/126673233