std::future怎么使用?

std::future 是 C++11 引入的一个类模板,用于表示一个异步操作的结果。它通常与 std::asyncstd::promise 或线程池等一起使用,以便在不阻塞当前线程的情况下获取其他线程或异步任务的结果。

以下是如何使用 std::future 的一些基本步骤和示例:

1. 使用 std::async 创建 std::future

std::async 是一个函数模板,它启动一个新的异步任务,并返回一个 std::future 对象,该对象表示该任务的结果。

#include <iostream>
#include <future>
#include <chrono>

int some_task() {
    std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟耗时操作
    return 42; // 返回结果
}

int main() {
    // 启动异步任务并获取表示结果的 std::future 对象
    std::future<int> result = std::async(std::launch::async, some_task);

    // 在这里可以做其他工作...

    // 获取异步任务的结果(这可能会阻塞,直到结果可用)
    int value = result.get();
    std::cout << "Result of async task: " << value << std::endl;

    return 0;
}

在这个例子中,std::async 启动了 some_task 函数作为一个异步任务,并返回一个 std::future<int> 对象。通过调用 result.get(),我们可以获取该任务的结果。注意,get() 函数是阻塞的,它会等待直到结果可用。

2. 使用 std::promisestd::future

有时候,你可能想要手动设置一个 std::future 的值,而不是通过 std::async。在这种情况下,你可以使用 std::promise 对象。

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

void set_value(std::promise<int> prom) {
    std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟耗时操作
    prom.set_value(42); // 设置 future 的值
}

int main() {
    // 创建一个 promise 对象
    std::promise<int> prom;
    // 获取与 promise 关联的 future 对象
    std::future<int> result = prom.get_future();

    // 在新线程中运行设置值的函数
    std::thread t(set_value, std::move(prom));

    // 在这里可以做其他工作...

    // 获取 future 的值(这可能会阻塞,直到值被设置)
    int value = result.get();
    std::cout << "Value set by promise: " << value << std::endl;

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

    return 0;
}

在这个例子中,我们创建了一个 std::promise<int> 对象,并通过调用 get_future() 获取了一个与之关联的 std::future<int> 对象。然后,我们在一个新线程中运行了 set_value 函数,该函数接受 std::promise 对象作为参数,并在模拟耗时操作后调用 set_value() 来设置 std::future 的值。

注意事项

  • std::futureget() 方法是阻塞的,它会等待直到结果可用。如果你不想阻塞,你可以使用 wait_forwait_until 方法来检查结果是否可用。
  • std::futurestd::promise 是线程安全的,可以在多个线程之间安全地共享和访问。
  • 如果你不再需要 std::future 的结果,你应该调用 std::future::discard_result() 来避免不必要的资源消耗。
  • std::promise 的对象被销毁且其关联的 std::future 尚未获取结果时,任何对 std::futureget() 调用都将抛出 std::future_error 异常。

std::futurewait_forwait_until 是两个用于等待异步操作结果的成员函数。它们允许你在不阻塞当前线程的情况下,检查与 std::future 关联的异步操作是否已经完成,或者是否已经达到了指定的等待时间。

wait_for 的使用方法

wait_for 函数接受一个表示等待时间的 std::chrono::duration 对象作为参数,并返回一个 std::future_status 枚举值,指示异步操作的状态。

template<class Rep, class Period>
std::future_status wait_for(const std::chrono::duration<Rep, Period>& timeout_duration) const;
  • timeout_duration:要等待的时间长度。
  • 返回值:std::future_status,可以是以下三个值之一:
    • std::future_status::ready:异步操作已经完成,结果已经就绪。
    • std::future_status::timeout:等待时间已过,但异步操作尚未完成。
    • std::future_status::deferred:如果 std::async 被调用时使用了 std::launch::deferred 策略,并且异步操作尚未被启动。

示例代码:

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

int some_task() {
    std::this_thread::sleep_for(std::chrono::seconds(3)); // 模拟耗时操作
    return 42; // 返回结果
}

int main() {
    // 启动异步任务并获取表示结果的 std::future 对象
    std::future<int> result = std::async(std::launch::async, some_task);

    // 等待异步任务2秒
    std::future_status status = result.wait_for(std::chrono::seconds(2));

    if (status == std::future_status::ready) {
        std::cout << "Task completed, result: " << result.get() << std::endl;
    } else if (status == std::future_status::timeout) {
        std::cout << "Task not completed within the specified time." << std::endl;
        // 可以选择继续等待或执行其他操作
    } else if (status == std::future_status::deferred) {
        std::cout << "Task is deferred and has not been started yet." << std::endl;
    }

    return 0;
}

wait_until 的使用方法

wait_until 函数接受一个表示绝对等待时间点的 std::chrono::time_point 对象作为参数,并返回一个 std::future_status 枚举值。

template<class Clock, class Duration>
std::future_status wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time) const;
  • timeout_time:要等待到的绝对时间点。
  • 返回值:与 wait_for 相同,为 std::future_status 枚举值。

示例代码:

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

int some_task() {
    std::this_thread::sleep_for(std::chrono::seconds(5)); // 模拟耗时操作
    return 42; // 返回结果
}

int main() {
    // 获取当前时间点并计算等待到的绝对时间点(当前时间+4秒)
    auto now = std::chrono::system_clock::now();
    auto timeout = now + std::chrono::seconds(4);

    // 启动异步任务并获取表示结果的 std::future 对象
    std::future<int> result = std::async(std::launch::async, some_task);

    // 等待异步任务直到指定的时间点
    std::future_status status = result.wait_until(timeout);

    if (status == std::future_status::ready) {
        std::cout << "Task completed, result: " << result.get() << std::endl;
    } else if (status == std::future_status::timeout) {
        std::cout << "Task not completed by the specified time." << std::endl;
        // 可以选择继续等待或执行其他操作
    } else if (status == std::future_status::deferred) {
        std::cout << "Task is deferred and has not been started yet." << std::endl;
    }

    return 0;
}

在这两个示例中,wait_forwait_until 分别用于等待异步操作完成一定的时间或直到指定的时间点。如果异步操作在这段时间内完成,std::future 的状态将变为 ready,并且你可以调用 get() 方法来获取结果。如果等待时间已过但异步操作尚未完成,状态将为 timeout,你可以根据需要决定是继续等待还是执行其他操作。如果异步操作被延迟执行(使用了 std::launch::deferred 策略),状态将为 deferred

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code .

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值