C++ promise类

Promise 是C++标准库中用于异步编程的类模板,通常用于从完成一项任务的执行线程返回结果给启动该任务的线程。在这里,Promise对象充当了一个临时的标志,并将在一些时刻被一个结果值所取代。

一个Promise对象有两方面的对等关系:

  • 一个Promise对象是为了保存某个特定的结果值分配的,这个结果值是在未来的某个时间点计算得到的。结果值可以是任意类型的值(void类型除外);也可以是指向常量和非常量(对象指针、函数或者成员函数)的指针;甚至是引用类型的“实值”。
  • 一个Promise对象可以创建一个或多个std::future对象,用来承载该Promise对象所保存的结果值。只有当set_value()或者set_exception()被调用,这些结果值才能被执行。一旦被执行,这些结果值就可以通过std::future::get函数添加到std::future对象中。

一个使用Promise的生产者-消费者示例:

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

void getData(std::promise<int>* prom_obj){
    //do something to get the data
    int data = 2;
    std::this_thread::sleep_for(std::chrono::seconds(2));
    prom_obj->set_value(data);
}

int main(){

    std::promise<int> promise_obj;
    std::future<int> future_obj = promise_obj.get_future();
    std::thread t(getData, &promise_obj);
  
    std::cout<<"Data received : "<<future_obj.get()<<std::endl;
    t.join();
    return 0;
}

在上述示例中,主线程创建了一个 promise 对象,并通过引用将其传递给新线程。新线程中执行一个获取数据的函数,该数据被存入 promise 对象中。
主线程通过调用从 promise 对象获取的 future 对象的get方法获取数据。需要注意的是,get方法是一个阻塞调用,它会一直等待,直到该数据可用。一旦数据可用,get就会返回数据。如果在设置数据值或异常之前销毁了 promise,get() 将抛出promise_broken 异常。

在异步编程中,可能会碰到这样的情况:比如创建了一个promise对象,然后在某个线程中通过get()访问它。然而,如果在调用get()之前,这个promise对象被析构(销毁),那个尝试获取结果的线程将会抛出std::future_error异常,其中error_code()将会返回std::future_errc::broken_promise。

一个显眼的处理方式就是确保promise对象的生命周期一直持续到已经调用set_value或者set_exception为止。除此之外,可以使用智能指针(例如std::shared_ptr)来管理promise对象的生命周期,确保promise对象在最后一个引用被释放时才被删除。

在捕获异常的时候,我们尽量做一些错误处理,使得程序还能使正常运行。例如:

std::promise<int> prom;
try {
    // ...
    prom.get_future().get();
}
catch (const std::future_error& e) {
    if (e.code() == std::future_errc::broken_promise)
        std::cout << "Caught broken_promise error\n";
    else
        std::cout << "Caught unexpected exception\n";
}

通过使用try-catch语句,当promise对象提前被析构时,我们可以捕获到这个异常,然后自行处理。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值