c++ 11 线程支持 (std::promise)

定义于头文件 <future>

template< class R > class promise;         (1) (C++11 起) 

template< class R > class promise<R&>;     (2) (C++11 起) 

template<> class promise<void>;            (3) (C++11 起) 

 

构造函数

promise();                                         (1) (C++11 起) 

template< class Alloc >
 promise( std::allocator_arg_t, const Alloc& alloc ); (2) (C++11 起) 

promise( promise&& other ) noexcept;              (3) (C++11 起) 

promise( const promise& other ) = delete;         (4) (C++11 起) 

构造 std::promise 对象。

1) 默认构造函数,构造一个共享状态为空的 std::promise

2) 构造一个共享状态为空的 std::promise,由 alloc 分配共享状态, Alloc 必须满足分配器 (Allocator) 的要求;

3) 移动构造函数,用原属 other 的共享状态构造新的 std::promise 对象,使用移动语义。构造完毕后, other 无共享状态;

4) std::promise 不可复制。

参数

alloc-分配器,用于分配共享状态;
other-另一 std::promise 对象,作为获得共享状态的来源。

异常

1-2) (无)

析构函数

~promise();                     (C++11 起) 

抛弃共享状态:

  • 若共享状态就绪,则释放它。
  • 若共享状态未就绪,则存储以 std::future_errc::broken_promise 为 error_condition 的 std::future_error 类型异常对象,令共享状态就绪再释放它。


赋值共享状态

promise& operator=( promise&& other ) noexcept;(1) (C++11 起) 

promise& operator=( const promise& rhs ) = delete; (2) (C++11 起) 

赋值内容。

1) 移动赋值运算符。首先,抛弃共享状态(如在 ~promise() 中),然后如同以执行 std::promise(std::move(other)).swap(*this) 对共享状态赋值。

2) std::promise 不可复制赋值。

参数

other-另一 std::promise 对象,为获取状态的来源

返回值

*this

交换二个 promise 对象

void swap( promise& other ) noexcept;      (C++11 起) 

交换二个 std::promise 对象的内容。

参数

other-与之交换的 std::promise 对象

返回值

(无)

返回与承诺的结果关联的 future

std::future<T> get_future();             (C++11 起) 

返回与 *this 关联同一状态的 future 对象。

若 *this 无共享状态,或已调用 get_future 则抛出异常。可使用 std::future::share 以获取 promise-future 交流通道的多个“弹出”端。

对此函数的调用与对 set_value 、 set_exception 、 set_value_at_thread_exit 或 set_exception_at_thread_exit 的调用不造成数据竞争(但它们不必彼此同步)。

参数

(无)

返回值

指代 *this 的共享状态的 future

异常

遇到下列条件时抛出 std::future_error :

  • *this 无共享状态。设置 error_category 为 no_state 。
  • 已在与 *this 拥有同一共享状态的 promise 上调用 get_future() 。设置 error_category 为 future_already_retrieved 。


​​​​​​​设置结果为指定值

void set_value( const R& value );(1) (C++11 起)(仅为泛型 promise 模板的成员) 

void set_value( R&& value );(2) (C++11 起) (仅为泛型 promise 模板的成员) 

void set_value( R& value );(3) (C++11 起)  (仅为 promise<R&> 模板特化的成员) 

void set_value(); (4)  (C++11 起)  (仅为 promise<void> 模板特化的成员) 

1-3) 原子地存储 value 到共享状态,并令状态就绪。

4) 使状态就绪。

set_value 、 set_exception 、 set_value_at_thread_exit 和 set_exception_at_thread_exit 的操作表现类似。在更新 promise 对象时获得单个与 promise 对象关联的互斥。

若无共享状态或共享状态已存储值或异常,则抛出异常。

对此函数的调用和对 get_future 的调用不会造成数据竞争(但它们不需要彼此同步)。

参数

value-要存储于共享状态的值

返回值

(无)

异常

遇到下列条件时为 std::future_error :

  • *this 无共享状态。设置 error_category 为 no_state 。
  • 共享状态已存储值或异常。设置 error_category 为 promise_already_satisfied 。

另外;

1, 3) value 的复制构造函数所抛的任何异常

2) value 的移动构造函数所抛的任何异常

调用示例

#include <thread>
#include <future>
#include <cctype>
#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <sstream>

int main()
{
    std::istringstream iss_numbers{"3 4 1 42 23 -23 93 2 -289 93"};
    std::istringstream iss_letters{" a 23 b,e a2 k k?a;si,ksa c"};

    std::vector<int> numbers;
    std::vector<char> letters;
    std::promise<void> numbers_promise, letters_promise;

    auto numbers_ready = numbers_promise.get_future();
    auto letter_ready = letters_promise.get_future();

    std::thread value_reader([&]
    {
        // I/O 操作。
        std::copy(std::istream_iterator<int>{iss_numbers},
        std::istream_iterator<int>{},
        std::back_inserter(numbers));

        // 为数字提醒。
        numbers_promise.set_value();

        std::copy_if(std::istreambuf_iterator<char>{iss_letters},
        std::istreambuf_iterator<char>{},
        std::back_inserter(letters),
        ::isalpha);

        // 为字母提醒。
        letters_promise.set_value();
    });


    numbers_ready.wait();

    std::sort(numbers.begin(), numbers.end());

    if (letter_ready.wait_for(std::chrono::seconds(1)) ==
            std::future_status::timeout)
    {
        // 在获得字母的同时输出数
        for (int num : numbers)
        {
            std::cout << num << ' ';
        }
        numbers.clear(); //Numbers were already printed.
    }

    letter_ready.wait();
    std::sort(letters.begin(), letters.end());

    // 若已打印数,则不做任何事。
    for (int num : numbers)
    {
        std::cout << num << ' ';
    }
    std::cout << '\n';

    for (char let : letters)
    {
        std::cout << let << ' ';
    }
    std::cout << '\n';

    value_reader.join();
}

输出

 

设置结果为指定值,同时仅在线程退出时分发提醒

void set_value_at_thread_exit( const R& value ); (1) (C++11 起)
(仅为泛型 promise 模板的成员) 

void set_value_at_thread_exit( R&& value );  (2) (C++11 起)
(仅为泛型 promise 模板的成员) 

void set_value_at_thread_exit( R& value ); (3) (C++11 起)
(仅为 promise<R&> 模板特化的成员) 

void set_value_at_thread_exit();  (4) (C++11 起)
(仅为 promise<void> 模板特化的成员) 

原子地存储 value 到共享状态,而不立即令状态就绪。在当前线程退出时,销毁所有拥有线程局域存储期的对象后,再令状态就绪。

set_value 、 set_exception 、 set_value_at_thread_exit 和 set_exception_at_thread_exit 的操作表现类似。在更新 promise 对象时获得单个与 promise 对象关联的互斥。

若无共享状态或共享状态已存储值或异常,则抛出异常。

对此函数的调用和对 get_future 的调用不会造成数据竞争(但它们不需要彼此同步)。

参数

value-要存储于共享状态的值

返回值

(无)

异常

遇到下列条件时为 std::future_error :

  • *this 无共享状态。设置 error_category 为 no_state 。
  • 共享状态已存储值或异常。设置 error_category 为 promise_already_satisfied 。

另外;

1, 3) value 的复制构造函数所抛的任何异常

2) value 的移动构造函数所抛的任何异常

调用示例

#include <iostream>
#include <future>
#include <thread>
#include <chrono>

int main()
{
    std::promise<int> p;
    std::future<int> f = p.get_future();
    std::thread([&p]
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        p.set_value_at_thread_exit(9);
    }).detach();

    std::cout << "Waiting..." << std::flush;
    f.wait();
    std::cout << "Done!\nResult is: " << f.get() << '\n';
}

输出

 
设置结果为指示异常

void set_exception( std::exception_ptr p );            (C++11 起) 

存储异常指针 p 到共享状态中,并令状态就绪。

set_value 、 set_exception 、 set_value_at_thread_exit 和 set_exception_at_thread_exit 的操作表现类似。在更新 promise 对象时获得单个与 promise 对象关联的互斥。

若无共享状态,或共享状态已存储值或异常,则抛出异常。

对此函数的调用和对 get_future 的调用不会造成数据竞争(但它们不需要彼此同步)。

参数

p-要存储的异常指针。若 p 为空则行为未定义。

返回值

(无)

异常

遇到下列条件时为 std::future_error :

  • *this 无共享状态。设置 error_category 为 no_state 。
  • 共享状态已存储值或异常。设置 error_category 为 promise_already_satisfied 。

调用示例

#include <thread>
#include <iostream>
#include <future>

int main()
{
    std::promise<int> p;
    std::future<int> f = p.get_future();

    std::thread t([&p]
    {
        try
        {
            // 可能抛出的代码
            throw std::runtime_error("Example");
        }
        catch (...)
        {
            try
            {
                // 存储任何抛出的异常于 promise
                p.set_exception(std::current_exception());
            }
            catch (...) {}  // set_exception() 亦可能抛出
        }
    });

    try
    {
        std::cout << f.get();
    }
    catch (const std::exception& e)
    {
        std::cout << "Exception from the thread: " << e.what() << '\n';
    }
    t.join();
}

 输出

 

设置结果为指示异常,同时仅在线程退出时分发提醒

void set_exception_at_thread_exit( std::exception_ptr p );  (C++11 起) 

存储异常指针 p 到共享状态中,而不立即使状态就绪。在当前线程退出时,销毁所有拥有线程局域存储期的变量后,再零状态就绪。

set_value 、 set_exception 、 set_value_at_thread_exit 和 set_exception_at_thread_exit 的操作表现类似。在更新 promise 对象时获得单个与 promise 对象关联的互斥。

若无共享状态,或共享状态已存储值或异常,则抛出异常。

对此函数的调用和对 get_future 的调用不会造成数据竞争(但它们不需要彼此同步)。

参数

p-要存储的异常指针。若 p 为空则行为未定义。

返回值

(无)

异常

遇到下列条件时为 std::future_error :

  • *this 无共享状态。设置 error_category 为 no_state 。
  • 共享状态已存储值或异常。设置 error_category 为 promise_already_satisfied 。

调用示例

#include <thread>
#include <iostream>
#include <future>

int main()
{
    std::promise<int> p;
    std::future<int> f = p.get_future();

    std::thread t([&p]
    {
        try
        {
            // 可能抛出的代码
            throw std::runtime_error("Example");
        }
        catch (...)
        {
            try
            {
                // 存储任何抛出的异常于 promise
                p.set_exception(std::current_exception());
            }
            catch (...) {}  // set_exception() 亦可能抛出
        }

        std::cout << "thread t end" << std::endl;
    });

    try
    {
        std::cout << f.get();
    }
    catch (const std::exception& e)
    {
        std::cout << "Exception from the thread: " << e.what() << '\n';
    }
    t.join();
}

输出

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值