folly::future 构造后不会自动执行,必须通过 via 指定 executor(如 folly::getcpuexecutor())或调用 wait()/get() 才能触发执行链;异常由 folly::exception_wrapper 封装,经 thenerror/onerror 处理,thenvalue 遇异常直接跳过。

folly::Future 构造后不执行,怎么让它真正跑起来
folly::Future 本身只是个值容器和状态机,不是线程、也不自动调度——它不执行任何异步逻辑,只负责传递结果。你得手动把工作交给 folly::Executor 或显式触发(比如用 via、thenValue 绑定回调)。
常见错误现象:Future 创建后程序退出,回调没被调用;或 get() 卡死——本质是没启动执行链。
- 必须用
via指定执行器,例如folly::getCPUExecutor()或自定义线程池 - 如果只是测试,可用
wait()或get()阻塞等待,但生产环境慎用——它会阻塞当前线程,且无法取消 -
makeFuture()和makeSemiFuture()行为不同:前者默认无 executor 绑定,后者更轻量但需显式via才能跨线程
示例:
auto f = folly::makeFuture(42)
.via(folly::getCPUExecutor())
.thenValue([](int x) { return x * 2; });这里 via 是关键,否则 thenValue 回调可能在调用线程同步执行(甚至不执行,取决于 future 状态)。folly::Future 链中如何捕获异常
folly 不靠 try/catch 传播异常,而是把异常封装进 folly::exception_wrapper,走错误路径。一旦某个 stage 抛异常,后续 thenValue 被跳过,转而匹配 thenError 或 onError。
使用场景:网络请求失败、解析出错、超时等需要分类型处理的错误分支。
-
thenValue只接收成功值,遇到异常直接跳过 -
thenError接收folly::exception_wrapper,可进一步用get_exception<:runtime_error>()</:runtime_error>提取原始异常 - 别写空的
thenError——没做处理就丢掉异常,debug 时会找不到源头 - 注意
onError和thenError的参数签名差异:thenError第一个参数是folly::exception_wrapper,onError是模板推导类型
示例:
f.thenValue([](int x) { throw std::runtime_error("boom"); })
.thenError([](folly::exception_wrapper ew) {
if (auto e = ew.get_exception<:runtime_error>()) {
LOG(ERROR) what();
}
});</:runtime_error>
folly::SemiFuture 和 Future 混用时容易卡死
folly::SemiFuture 是无 executor 的“半成品”,不能直接 via 或 get;它必须先转成 Future(通过 via),否则调用 get() 会 crash 或 hang。
常见错误现象:对 SemiFuture 直接调用 get(),程序 SIGABRT;或 via 传了 null executor,导致后续链不执行。
-
SemiFuture适合 IO 密集型操作起点(如AsyncSocket::read返回的就是它),避免过早绑定线程 - 转换必须带非空
Executor:semiFuture.via(executor)→Future - 不能把
Future往回转成SemiFuture——没提供接口,强行 cast 会 UB - 性能影响:
SemiFuture内存开销略小,但多一次via调用,延迟增加纳秒级,通常可忽略
多个 Future 并发等待:wait、collect、collectAll 区别在哪
folly 提供三组聚合工具,语义和失败策略完全不同,选错会导致逻辑意外终止或掩盖错误。
-
collect:全成功才返回 vector,任一失败则整个 future 失败(抛第一个异常) -
collectAll:不管成败都返回vector<try>></try>,每个元素需手动检查hasValue()或hasException() -
wait:仅用于单个 future 阻塞等待,**不是**并发等待接口——名字有误导性,别被带偏 - 注意
collect对空 vector 返回 ready future;collectAll同样支持空输入,但返回空 vector
示例:
auto fs = std::vector{f1, f2, f3};
folly::collect(fs).thenValue([](std::vector<int> v) {
// v 一定全成功,长度=3
});
folly::collectAll(fs).thenValue([](std::vector<:try>> v) {
// 每个 v[i] 都要 check,可能混着 success/failure
});</:try></int>
最容易被忽略的是 collectAll 的返回类型——它不帮你解包,Try 必须显式处理,漏掉就等于静默吞异常。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











