0
点赞
收藏
分享

微信扫一扫

UNIX(多线程):17---异步任务提供者(Provider) 介绍

​std::promise​​ 类概述

Promise 对象可以保存某一类型 T 的值,该值可被 future 对象读取(可能在另外一个线程中),因此 promise 也提供了一种线程同步的手段。在 promise 对象构造时可以和一个共享状态(通常是std::future)相关联,并可以在相关联的共享状态(​​std::future​​)上保存一个类型为 T 的值。

可以通过 ​​get_future​​ 来获取与该 promise 对象相关联的 future 对象,调用该函数之后,两个对象共享相同的共享状态(shared state)

  1. promise 对象是异步 Provider,它可以在某一时刻设置共享状态的值。
  2. future 对象可以异步返回共享状态的值,或者在必要的情况下阻塞调用者并等待共享状态标志变为 ready,然后才能获取共享状态的值。

下面以一个简单的例子来说明上述关系:

#include <iostream>       // std::cout
#include <functional> // std::ref
#include <thread> // std::thread
#include <future> // std::promise, std::future


void print_int(std::future<int>& fut) {
int x = fut.get(); // 获取共享状态的值.
std::cout << "value: " << x << '\n'; // 打印 value: 10.
}


int main ()
{
std::promise<int> prom; // 生成一个 std::promise<int> 对象.
std::future<int> fut = prom.get_future(); // 和 future 关联.
std::thread t(print_int, std::ref(fut)); // 将 future 交给另外一个线程t.
prom.set_value(10); // 设置共享状态的值, 此处和线程t保持同步.
t.join();
return 0;
}

​std::promise​​ 构造函数

default (1)

promise();

with allocator (2)

template <class Alloc> promise (allocator_arg_t aa, const Alloc& alloc);

copy [deleted] (3)

promise (const promise&) = delete;

move (4)

promise (promise&& x) noexcept;

  1. 默认构造函数,初始化一个空的共享状态。
  2. 带自定义内存分配器的构造函数,与默认构造函数类似,但是使用自定义分配器来分配共享状态。
  3. 拷贝构造函数,被禁用。
  4. 移动构造函数。

另外,​​std::promise​​​ 的 ​​operator=​​​ 没有拷贝语义,即 ​​std::promise​​​ 普通的赋值操作被禁用,​​operator=​​​ 只有 move 语义,所以 ​​std::promise​​ 对象是禁止拷贝的。

例子:

#include <iostream>       // std::cout
#include <thread> // std::thread
#include <future> // std::promise, std::future


std::promise<int> prom;


void print_global_promise () {
std::future<int> fut = prom.get_future();
int x = fut.get();
std::cout << "value: " << x << '\n';
}

int main ()
{
std::thread th1(print_global_promise);
prom.set_value(10);
th1.join();

prom = std::promise<int>(); // prom 被move赋值为一个新的 promise 对象.

std::thread th2 (print_global_promise);
prom.set_value (20);
th2.join();

return 0;
}

​std::promise::get_future​​ 介绍

该函数返回一个与 promise 共享状态相关联的 future 。返回的 future 对象可以访问由 promise 对象设置在共享状态上的值或者某个异常对象。只能从 promise 共享状态获取一个 future 对象。在调用该函数之后,promise 对象通常会在某个时间点准备好(设置一个值或者一个异常对象),如果不设置值或者异常,promise 对象在析构时会自动地设置一个 ​​future_error​​​ 异常(​​broken_promise​​​)来设置其自身的准备状态。上面的例子中已经提到了 ​​get_future​​,此处不再重复。

​std::promise::set_value​​ 介绍

generic template (1)

void set_value (const T& val);

void set_value (T&& val);

specializations (2)


void promise<R&>::set_value (R& val);

// when T is a reference type (R&)

void promise<void>::set_value (void);

// when T is void


设置共享状态的值,此后 promise 的共享状态标志变为 ​​ready​​.

​std::promise::set_exception​​ 介绍

为 promise 对象设置异常,此后 promise 的共享状态变标志变为 ​​ready​​​,例子如下,线程1从终端接收一个整数,线程 2 将该整数打印出来,如果线程 1 接收一个非整数,则为 promise 设置一个异常(failbit) ,线程 2 在 ​​std::future::get​​ 是抛出该异常。

#include <iostream>       // std::cin, std::cout, std::ios
#include <functional> // std::ref
#include <thread> // std::thread
#include <future> // std::promise, std::future
#include <exception> // std::exception, std::current_exception


void get_int(std::promise<int>& prom) {
int x;
std::cout << "Please, enter an integer value: ";
std::cin.exceptions (std::ios::failbit); // throw on failbit
try {
std::cin >> x; // sets failbit if input is not int
prom.set_value(x);
} catch (std::exception&) {
prom.set_exception(std::current_exception());
}
}


void print_int(std::future<int>& fut) {
try {
int x = fut.get();
std::cout << "value: " << x << '\n';
} catch (std::exception& e) {
std::cout << "[exception caught: " << e.what() << "]\n";
}
}

int main ()
{
std::promise<int> prom;
std::future<int> fut = prom.get_future();

std::thread th1(get_int, std::ref(prom));
std::thread th2(print_int, std::ref(fut));

th1.join();
th2.join();
return 0;
}

​std::promise::set_value_at_thread_exit​​ 介绍

设置共享状态的值,但是不将共享状态的标志设置为 ​​ready​​​,当线程退出时该 promise 对象会自动设置为 ready。如果某个 ​​std::future​​​ 对象与该 promise 对象的共享状态相关联,并且该 future 对象正在调用 ​​get​​​,则调用 get 的线程会被阻塞,当线程退出时,调用 ​​future::get​​​ 的线程解除阻塞,同时 ​​get​​​ 返回 ​​set_value_at_thread_exit​​​ 所设置的值。注意,该函数已经设置了 promise 共享状态的值,如果在线程结束之前有其他设置或者修改共享状态的值的操作,则会抛出 ​​future_error​​​( ​​promise_already_satisfied​​ )。

​std::promise::swap​​ 介绍

交换 promise 的共享状态。



举报

相关推荐

0 条评论