C++ 异步库

本文详细介绍了C++11标准库中的异步编程组件,包括std::future用于封装异步结果、std::packaged_task将函数与future结合、std::async创建异步任务、std::promise用于值传递和std::shared_future的共享异步结果。讨论了它们的使用方法和注意事项。
摘要由CSDN通过智能技术生成

C++ 异步库

std::future && std::packaged_task

std::future是C++11标准库中提供的用于异步计算的核心组件之一。它代表了一个可能还未完成的异步计算的结果。通过使用std::future,开发者可以在主线程或其他线程发起一个异步操作,并能够在将来某个时刻查询操作的状态、等待操作完成或者获取操作的结果。

  • std::future提供了如下主要功能:
  1. 异步操作结果的封装:一个std::future对象可以存储由异步操作产生的任何类型的结果。
  2. 阻塞等待:通过调用std::future::get()方法,当前线程可以阻塞等待异步操作完成并获取其结果。
  3. 检查状态:通过std::future::valid()std::future::wait()std::future::wait_for()std::future::wait_until()等方法可以检查异步操作是否已经完成。
  4. 共享结果:多个std::future对象可以关联到同一个异步操作的结果,从而允许多个线程或函数安全地访问同一份数据。
  5. 异常处理:如果异步操作抛出了异常,那么当尝试获取std::future的结果时,该异常会被重新抛出。
  • std::packaged_task是C++11标准库中提供的另一种用于异步编程的工具,它将一个可调用对象(如函数、lambda表达式或仿函数)与std::future结合在一起。通过创建一个std::packaged_task对象,可以将任务打包起来,并且每次调用std::packaged_task::get_future()都会得到一个与之关联的std::future对象,这个future可以用来获取任务完成后产生的结果。

基本使用格式如下:

std::packaged_task<ResultType(ParamTypes...)> task(Function);
std::future<ResultType> future = task.get_future();

例如:

#include <future>
#include <iostream>

// 定义一个计算平方的函数
int square(int x) {
    return x * x;
}

int main() {
    // 创建一个包装任务,将square函数与其绑定
    std::packaged_task<int(int)> task(square);

    // 获取与该任务关联的future
    std::future<int> result_future = task.get_future();

    // 将任务提交到另一个线程执行
    std::thread worker(std::move(task), 10); // 使用std::move避免复制任务

    // 主线程可以继续执行其他任务...

    // 等待future的结果
    int result = result_future.get();
    std::cout << "The square of 10 is: " << result << std::endl;

    // 确保worker线程结束
    worker.join();

    return 0;
}

在这个例子中,std::packaged_tasksquare函数打包,创建一个可以异步执行的任务,并通过get_future()获取到任务完成后的结果的std::future。之后,任务被移动到新的线程中执行,主线程通过result_future.get()等待并获取计算结果。

std::async

std::async用于创建异步任务的功能。它允许你在不同的线程上执行函数调用,返回一个std::future对象,该对象可用于获取异步调用的结果。

基本使用格式如下:

std::future<ReturnType> future = std::async(std::launch::policy, Function, Args...);
  • std::launch::policy 是一个枚举类型,用于指定如何启动任务。可能的选项包括 std::launch::async (强制异步执行)和 std::launch::deferred (延迟执行,只有当获取未来对象的结果时才执行)以及默认策略(根据实现决定是立即执行还是延迟执行)。

  • Function 是要异步调用的函数或者可调用对象,可以带任意数量的参数 Args...

例如:

#include <future>
#include <iostream>

int heavyComputation(int n) {
    // 模拟耗时操作
    std::this_thread::sleep_for(std::chrono::seconds(1));
    return n * n;
}

int main() {
    std::future<int> fut = std::async(std::launch::async, heavyComputation, 10);

    std::cout << "Doing some other work..." << std::endl;

    // 获取异步任务的结果,这一步可能阻塞直到结果可用
    int result = fut.get();
    std::cout << "The result of the computation is: " << result << std::endl;

    return 0;
}

在这个例子中,heavyComputation函数在一个单独的线程上异步执行,主线程可以继续执行其他任务,然后通过调用fut.get()来等待并获取计算结果。

std::promise

std::promise是C++11标准库中用于异步编程的一个组件,它与std::future配对使用,允许在不同线程间传递和接收值。std::promise对象可以设置(或“承诺”)一个值,而与之相关联的std::future对象可以获取(或“期待”)这个值。

基本使用格式如下:

std::promise<TYPE> promise_obj; // 创建一个承诺对象,承诺一个TYPE类型的值
std::future<TYPE> future_obj = promise_obj.get_future(); // 从承诺对象获取一个future对象

// 在某个线程中设置承诺的值
promise_obj.set_value(VALUE);

// 在另一个线程中通过future对象获取承诺的值(可能阻塞)
TYPE value = future_obj.get();

例如:

#include <future>
#include <iostream>

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

    // 启动一个新的线程来设置承诺的值
    std::thread thread([p = std::move(promise)]() mutable {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        p.set_value(42); // 设置承诺值为42
    });

    // 主线程等待并获取future的值
    int result = future.get();
    std::cout << "The promised value is: " << result << std::endl;

    // 确保线程结束
    thread.join();

    return 0;
}

在这个例子中,std::promise对象在新线程中设置了一个整数值,主线程通过与之关联的std::future对象获取这个值。当future.get()被调用时,若值尚未准备好,则调用线程将阻塞,直到值被设置为止。

std::shared_future

std::shared_future是C++11标准库中的一个类,它是std::future的共享版本,允许多个拥有者共享一个异步计算的结果。相比于std::futurestd::shared_future可以被多个对象共享并管理,即使原始的std::futurestd::promise对象被销毁,只要还有std::shared_future对象存在,异步计算的结果就能继续保持有效。

std::shared_future通常不是直接创建的,而是通过调用std::future::share()函数从std::future转换而来:

std::future<int> normalFuture = std::async([]{ return 42; });
std::shared_future<int> sharedFuture = normalFuture.share();

std::shared_future同样提供了类似于std::future的操作,如get()来获取异步计算的结果,wait()wait_for()wait_until()来等待结果准备就绪,以及检查状态的方法。

值得注意的是,由于涉及资源的共享,对std::shared_future的操作应当谨慎,特别是在并发环境中,以防止数据竞争和死锁等问题。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值