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
相关产品推荐
相关产品推荐

