C++ 并发三件套 - future, promise, async
C++标准库提供了很多用于并发编程的工具,不太熟悉,总结一下。
#异步计算结果 std::future<T>
std::future<T>
表示一个异步计算过程的结果。
std::future::wait()
方法阻塞当前线程直至计算完成。如果计算已经完成,则直接返回。
std::future::get()
方法等待计算完成,并获取 future<T>
表示的值或异常。get()
方法会消耗掉当前 future 保存的值,因此只能调用一次。
std::future::valid()
方法表示当前 future 中是否还有值可以被获取,如果值已经被 get 过,则会返回 false。
std::future::share()
方法返回一个 std::shared_future<T>
。
std::future<T>
是 move-only 的结构,且独占 T
的所有权。当多个对等的线程需要访问同一个期望值时,可以使用 copyable 的 std::shared_future<T>
。注意,std::shared_future<T>
本身并不是线程安全的,需要每个线程拷贝并持有一个自己的 std::shared_future<T>
。
#异步生产者 std::promise<T>
std::promise<T>
用于生产者提供一个 std::future<T>
及其中的值给消费者。std::promise<T>::get_future()
方法返回一个 std::future<T>
给消费者。
对于生产者,使用 std::promise<T>::set_value()
方法填充 future
中的值;或者使用 std::promise<T>::set_exception()
方法填充 future
中的异常;
1 | extern std::promise<double> some_promise; |
#异步执行 std::async()
std::async
是一个函数,它启动一个异步任务去执行指定的函数,返回一个表示计算结果的 std::future
std::async
允许额外指定一个std::launch
类型的参数来指定任务启动的方式,有以下几种启动策略:
std::launch::async
: 任务必须在独立线程中执行,因此需要库去负责线程创建和销毁;std::launch::deferred
: 任务可以延迟到wait()
或者get()
的时候,在调用者线程上同步执行 (有点类似Rust Tokio的设计);std::launch::async | std::launch::deferred
: 默认的方式,表示以上两种执行时机都可以,由具体实现去选择。