C++异步编程:future和promise的使用

2025-05发布6次浏览

C++异步编程是现代C++开发中的一个重要主题,std::futurestd::promise是C++11引入的用于支持异步操作的核心工具。它们提供了一种机制来管理异步任务的结果,并允许线程之间安全地传递数据。

下面我们将深入探讨std::futurestd::promise的概念、使用方法以及一些实际的例子。

1. 基本概念

  • Promise: 是一个容器,用来存储异步操作的结果。你可以通过它设置结果。
  • Future: 是一个占位符,表示某个时刻将会有可用的值。它是从promise中获取结果的对象。

两者的关系可以理解为:promise负责生产数据,而future负责消费数据。

2. 使用示例

2.1 创建并使用Promise和Future

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

void set_value(std::promise<int>& prom) {
    std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟耗时操作
    prom.set_value(42); // 设置结果
}

int main() {
    std::promise<int> prom;
    std::future<int> fut = prom.get_future(); // 获取关联的future

    std::thread t(set_value, std::ref(prom)); // 在另一个线程中设置promise的值

    std::cout << "Waiting for value..." << std::endl;
    int value = fut.get(); // 等待并获取结果
    std::cout << "Value is: " << value << std::endl;

    t.join();
    return 0;
}

在这个例子中,我们创建了一个promise对象,并通过它得到了一个future对象。然后在一个单独的线程中设置了promise的值。主程序通过调用fut.get()等待这个值,并在得到后打印出来。

2.2 处理异常

std::promise也可以用来传递异常:

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

void set_exception(std::promise<int>& prom) {
    try {
        throw std::runtime_error("Something went wrong!");
    } catch(...) {
        prom.set_exception(std::current_exception());
    }
}

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

    std::thread t(set_exception, std::ref(prom));

    try {
        std::cout << "Waiting for value..." << std::endl;
        int value = fut.get();
        std::cout << "Value is: " << value << std::endl;
    } catch(const std::exception& e) {
        std::cerr << "Caught exception: " << e.what() << std::endl;
    }

    t.join();
    return 0;
}

在这个例子中,如果在设置promise值的过程中抛出了异常,我们可以捕获这个异常并将其传递给future

3. 异步函数调用

除了手动创建线程,C++还提供了std::async函数来简化异步任务的创建:

#include <iostream>
#include <future>

int async_task(int x) {
    std::this_thread::sleep_for(std::chrono::seconds(2));
    return x * x;
}

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

    std::cout << "Waiting for result..." << std::endl;
    int result = fut.get();
    std::cout << "Result is: " << result << std::endl;

    return 0;
}

在这里,std::async自动为我们创建了一个线程来执行async_task函数,并返回一个future对象。

4. 流程图表示

为了更好地理解futurepromise的工作流程,我们可以使用以下流程图表示:

sequenceDiagram
    participant MainThread
    participant Promise
    participant Future
    MainThread->>Promise: Create promise
    MainThread->>Future: Get future from promise
    MainThread->>WorkerThread: Start worker thread
    WorkerThread->>Promise: Set value or exception
    Future-->>MainThread: Wait and get value/exception

结论

std::futurestd::promise为C++中的异步编程提供了强大的支持,使开发者能够更容易地处理多线程环境下的数据共享和同步问题。