【C++】C++11异步操作

目录

std::future

std::async函数模板

std::packaged_task类模板

std::promise类模板


std::future

std::future是C++11标准库中的一个模板类,它表示一个异步操作的结果,当我们在多线程编程中使用异步任务时,std::future可以帮助我们在需要的时候获取任务的执行结果。

std::future的一个重要特性是能够阻塞当前线程,直到异步操作完成,从而确保我们在获取结果时不会遇到未完成的操作。

当res.get()获取结果时,如果新线程还未返回结果,则阻塞。 然而,std::future并不能单独使用,需要搭配一些能够执行异步任务的模板类或函数一起使用。

异步任务搭配使用:

  • std::async函数模板:异步执行一个函数,返回一个future对象用于获取函数结果。
  • std::packaged_task类模板:为一个函数生成一个异步任务对象(可调用对象),用于在其他线程中执行。
  • std::promise类模板:实例化的对象可以返回一个future,在其他线程中向promise对象设置数据,其他线程的关联future就可以获取数据。

std::async函数模板

std::async是一个模板函数,内部会创建线程执行异步任务。

如下是一个异步非阻塞调用,返回结构实例化类型为int表示异步任务的返回结果是一个整型。

std::future<int> res=std::async(执行策略,异步任务,异步任务的参数1,异步任务的参数2..);

执行策略:

  • std::launch::deferred策略:同步策略,获取结果的时候再去执行任务。
  • std::launch::async策略:异步策略,内部创建一个线程执行函数,函数运行结果通过future获取
cpp 复制代码
#include <iostream>
#include <future>


//异步任务
int Add(int num1,int num2)
{
    return num1+num2;
}
int main()
{
    //进行了一个异步非阻塞调用
    std::future<int> res=std::async(std::launch::async,Add,11,22);

    //用于获取异步任务的结果,如果还没有结果就阻塞
    std::cout<<res.get()<<std::endl;
    return 0;
}

std::packaged_task类模板

std::packaged_task是一个类模板,也可以说是任务包,是对一个函数(任务)进行二次封装,封装成为一个可调用对象作为任务放到其他线程执行的。

任务包封装好了以后,可以在任意位置进行调用,通过关联的future来获取执行结果。

执行任务流程如下:

  1. 封装任务
  2. 获取任务包关联的future对象
  3. 执行任务
  4. 通过future获取任务执行结果

std::packaged_task因为与future对象有关联关系,不能进行赋值拷贝,因此创建时,建议使用智能指针,方便后面操作。

cpp 复制代码
#include <iostream>
#include <future>
#include <memory>

int Add(int num1,int num2)
{
    return num1+num2;
}
int main()
{
    //1、封装任务int(int,int) 对应 返回值(参数1,参数2)
    auto task=std::make_shared<std::packaged_task<int(int,int)>>(Add);

    //2、获取任务包关联的future对象
    std::future<int> res=task->get_future();

    //3、交给其他线程执行任务
    std::thread thr([task](){
        (*task)(11,22);
    });

    //4、获取结果
    std::cout<<res.get()<<std::endl;
    thr.join();
    return 0;
}

最后记得等待线程结束。

std::promise类模板

std::promise模板类,是对结果的封装。

使用步骤:

  1. 在使用的时候,就是先实例化一个指定结果的promise对象(promise对象类型必须与返回值类型一致)
  2. 通过promise对象,获取关联的future对象
  3. 在任意位置给promise设置数据,就可以通过关联的future获取到这个设置的数据了
cpp 复制代码
#include <iostream>
#include <future>
#include <memory>

int Add(int num1,int num2)
{
    return num1+num2;
}
int main()
{
    // 1、在使用的时候,就是先实例化一个指定结果的promise对象(promise对象类型必须与返回值类型一致)
    std::promise<int> pro;
    // 2、通过promise对象,获取关联的future对象
    std::future<int> res=pro.get_future();
    // 3、在任意位置给promise设置数据,就可以通过关联的future获取到这个设置的数据了
    std::thread thr([&pro](){
        int sum=Add(11,22);
        pro.set_value(sum);
    });

    std::cout<<res.get()<<std::endl;
    thr.join();
    return 0;
}
相关推荐
xailorliu1 小时前
SLIC_超像素算法
c++·opencv·目标检测·机器学习·计算机视觉
苏打豆1 小时前
CRISP源码阅读——基于ROS2力矩反馈控制器与速度加速度零空间
c++·线性代数·算法·矩阵·机器人
周杰偷奶茶2 小时前
【Java】数组的定义和使用(附管理系统实战案例)
java·开发语言
小小龙学IT2 小时前
snap7 开源西门子 S7 通信协议库深度解析
c++·开源
橙子圆1232 小时前
JUC之集合类不安全
java·开发语言
阿里嘎多学长3 小时前
2026-09-29 GitHub 热点项目精选
开发语言·程序员·github·代码托管
Bruce_Liuxiaowei3 小时前
网页版 DeepSeek “harness desktop“ WebGL 上下文创建失败排查实录
开发语言·javascript·webgl
狗凯之家源码网3 小时前
PHP 用户反馈系统源码深度评测与实战指南
开发语言·php·用户反馈系统
小溪学编程3 小时前
从 C++ 的规范变迁看语言发展
jvm·c++·面试
白山编程大哥3 小时前
Lua 中使用 C 语言的用户自定义类型——userdata
c语言·junit·lua