当前位置: 首页 > news >正文

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();
}

输出

 

相关文章:

  • 一篇文章带你看清C语言中的类型转换规则
  • 单海军:行业AI平台赋能金融企业数智化转型
  • Jmeter接口自动化(十)断言
  • C++ 小游戏 视频及资料集(7)
  • 计算机网络笔记(王道考研) 第二章:物理层
  • TCP的连接过程——三次握手和四次挥手
  • tensorflow2从入门到精通——DCGAN算法实现
  • 反欺诈黑产总结
  • 学术报告系列(七) - Critical Scenario Based SOTIF Validation Method
  • [ vulhub漏洞复现篇 ] JBOSS AS 5.x/6.x反序列化远程代码执行漏洞CVE-2017-12149
  • UE4 Http协议实现Web登陆与注册
  • 【线性代数基础进阶】二次型-补充+练习
  • mybatis-mybatis连接sqlserver数据库,maven
  • 融云 IM 即时通讯的跨应用通信能力
  • 行业发展解读:互联网人,如何“变道”自动驾驶?
  • php的引用
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • Android开源项目规范总结
  • angular2 简述
  • EventListener原理
  • Odoo domain写法及运用
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • XForms - 更强大的Form
  • 大快搜索数据爬虫技术实例安装教学篇
  • 分享几个不错的工具
  • 汉诺塔算法
  • 机器学习 vs. 深度学习
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 听说你叫Java(二)–Servlet请求
  • 为视图添加丝滑的水波纹
  • 我与Jetbrains的这些年
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • puppet连载22:define用法
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • #stm32驱动外设模块总结w5500模块
  • #vue3 实现前端下载excel文件模板功能
  • (06)金属布线——为半导体注入生命的连接
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (Matlab)使用竞争神经网络实现数据聚类
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (安卓)跳转应用市场APP详情页的方式
  • (第二周)效能测试
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (附源码)计算机毕业设计大学生兼职系统
  • (七)Java对象在Hibernate持久化层的状态
  • .libPaths()设置包加载目录
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • /deep/和 >>>以及 ::v-deep 三者的区别
  • @configuration注解_2w字长文给你讲透了配置类为什么要添加 @Configuration注解
  • @PreAuthorize注解
  • @zabbix数据库历史与趋势数据占用优化(mysql存储查询)