You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

boost::future带延续的调度与生命周期问题咨询

Boost.Future延续的执行条件与生命周期问题

你的代码中,延续b和c不会被执行,核心原因是代表延续任务的boost::future对象(即b和c)在calculate_foo函数返回时被销毁了,Boost.Future的延续调度依赖于持有该延续的future对象的生命周期。

具体原理

  • 调用s.then(...)会返回一个新的boost::future对象,这个对象是延续任务的“持有者”——如果该对象被销毁,且延续任务尚未开始执行,Boost会直接取消这个延续的调度,避免无主任务引发资源泄漏或未定义行为。
  • 你的代码里,b和c是calculate_foo的局部变量,函数返回时它们被立即析构。此时即便父shared_future s被返回并在main中等待,也无法挽救已经被取消的延续任务。

解决方法

要让延续执行,必须保证代表延续的future对象生命周期覆盖到任务完成的时间点,以下是两种可行方案:

方案1:保存延续的future对象

将b、c和父future一起返回,延长它们的生命周期到main函数中:

#include <iostream>
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#include <boost/thread/future.hpp>
#include <tuple>

auto calculate_foo(int input) {
    auto a = boost::async([input]{
        std::cout << input << std::endl;
        return input * 2;
    });

    auto s = a.share();

    auto b = s.then([](auto t) {
        auto v = t.get();
        std::cout << v << std::endl;
        boost::this_thread::sleep_for(boost::chrono::milliseconds(v));
    });

    auto c = s.then([](auto t) {
        auto v = t.get();
        std::cout << v << std::endl;
        boost::this_thread::sleep_for(boost::chrono::milliseconds(v));
    });

    return std::make_tuple(std::move(s), std::move(b), std::move(c));
}

int main() {
    auto [z, b, c] = calculate_foo(1000);
    z.wait();
    // 等待延续任务执行完毕
    b.wait();
    c.wait();
    return 0;
}

方案2:绑定延续到父future的生命周期(不推荐)

如果不需要关心延续结果,也可以通过一些技巧让延续与父future绑定,但这种方式可读性差且容易出错,更推荐方案1。

额外注意

Boost.Future的延续行为和C++17标准库的std::future::then有差异:标准库中延续的执行不依赖于返回的future对象,只要父future完成,延续就会被调度;但Boost基于旧提案实现,因此有严格的生命周期依赖。

内容的提问来源于stack exchange,提问作者Blair Davidson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 22:06:23