栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++多线程 task--std::promise和std::future

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++多线程 task--std::promise和std::future

0 引言

本文主要讲解C++11/14/17中所提供的应用于多线程编程中的Task机制。

Task可由如下几部分取得

  • std::async
  • std::packaged_task
  • std::promise和std::future

而本文主要讲解std::promise和std::future相关的内容。

std::promise和std::future通过一个数据管道进行交流,可以将std::promise看作生产者,std::future看作消费者,其两者形成如下的方式交互

1 std::promise 

std::promise本身是一个模版类,通过std::promise可以像数据管道中设置value,异常和相应的通知信息。

std::promise提供了如下接口

get_future()               // 返回相应的future

set_value()                // 设置一个相应的值

set_exception()            // 设置一个异常

set_value_at_thread_exit() // 设置一个值,当线程退出时,promise使数据管道中相应值的状态变为ready

set_exception_at_thread_exit()

如果std::promise设置值或者异常超过一次,那么会抛出std::future_error异常。

2 std::future

std::future本身是一个模版类,且其是不可拷贝对象, 可类比std::unique_ptr, 对其所管理的资源具有独占权。

通过std::future,你可以

  • 从std::promise获得相应的值
  • 询问std::promise是否将值设置为可用
  • 等待std::promise的通知。这个等待可以设置一个相对时间间隔或者一个绝对时间
  • 创建一个共享的future(std::shared_future)

std::future提供了如下主要接口

share()                         // 返回一个std::shared_future

get()                           // 从数据管道获得一个值或者异常

valid()                         // 检查共享状态是否有效,当调用完get接口后,该函数返回false

wait()                          // 等待结果

wait_for()                      // 等待结果,这个接口会等待一个时间间隔,其返回值为std::future_status

wait_until()                    // 等待结果,该接口会等待到一个绝对时间点,返回值为std::future_status
3 std::future_status

由上述知,future的wait_for和wait_until接口的返回值为std::future_status. 在C++11标准中,该值定义如下

enum class future_status {

    ready,
    timeout,
     deferred
};

其相应的描述如下所示

ready: 数据管道中的结果已经ready,也即可用

timeout: 数据管道中的数据不可用,且wait等待时间已经到达

deferred: 接口被延迟执行,也即还未开始

4 示例代码

本部分代码部分来自《C++ Concurrency in Action》,其具体示例如下所示

#include 
#include 
#include 
#include 

void setval(std::promise& p ,int a) {
  try {
    if (a == 0) {
      throw std::runtime_error("set value 0 not perimted");
    } else {
      // 设置相应的值
      p.set_value(a);
    }
  } catch(...) {
    // 设置异常,std::current_exception捕获当前异常
    p.set_exception(std::current_exception());
  } 
}

int main() {
  std::promise prom;
  auto fut = prom.get_future();

  std::thread t1(setval, std::ref(prom), 0);
  try {
    std::cout << "fut get value: " << fut.get() << "n";
  } catch(std::exception& ptr) {
    std::cout << ptr.what() << "n";
  }
  
  t1.join();
  return 0;
}

注意:在linux平台需要加上 -lpthread进行相应的构建。

上述相应的输出如下所示

fut get value: set value 0 not perimted

5 总结

本文总结了std::promise和std::future的相关概念及其使用。std::promise和std::future一般需要成对出现,用于构建C++多线程中Task。

std::promise和std::future不需要锁等同步措施,其内部本身进行了相应的同步,其使用比mutex要简单方便。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/997929.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号