第一个任务
学习目标
使用 Executor::instance() 获取 Facade,通过 submit_auto() 提交一个返回 42 的任务,并通过 future.get() 获取结果和异常。
场景问题
你需要把一段计算移到后台执行,但调用方仍要可靠地获得结果或得知它失败了。
推荐方案
使用 submit_auto()。普通 lambda 的默认意图是 Auto,当前只选择默认异步线程池;它返回 std::future:任务成功时 get() 返回值,任务抛出异常时 get() 在调用方线程重新抛出异常。首次提交会使用默认配置完成懒初始化。
这不是“从所有执行器中自动选最快一个”:普通 lambda 不会改投 GPU、无锁或实时执行器。需要知道 submit_auto、dispatch_auto 和 start_worker 如何按 intent 与名称精确匹配目标时,阅读自动路由如何匹配目标。
cpp
#include <exception>
#include <iostream>
#include <stdexcept>
#include <executor/executor.hpp>
int main() {
auto& executor = executor::Executor::instance();
auto answer = executor.submit_auto([] { return 42; });
std::cout << "answer=" << answer.get() << '\n';
const auto decision = executor.get_last_routing_decision();
if (!decision || decision->selected_backend != executor::ExecutionBackend::DefaultAsync) {
std::cerr << "unexpected routing decision\n";
executor.shutdown();
return 1;
}
auto failing_task = executor.submit_auto([]() -> int {
throw std::runtime_error("expected tutorial failure");
});
try {
static_cast<void>(failing_task.get());
} catch (const std::exception& error) {
std::cout << "task failed: " << error.what() << '\n';
}
executor.shutdown();
return 0;
}完整源码:examples/tutorial/01_first_task.cpp。
bash
./build/examples/tutorial/tutorial_01_first_task预期输出
text
answer=42
task failed: expected tutorial failure为什么这样做
future.get()不只是取值,也是异常传播边界;忽略它会让失败不再由这里观察。get_last_routing_decision()显示本次默认选择;它解释“为什么走这条路径”,不替代 future 的完成或异常结果。- 默认配置允许懒初始化,适合这个最小示例。
- 需要自定义线程数、队列容量或监控时,必须在第一次提交前调用
initialize_ex()。 - 示例最后调用
shutdown();这里没有待处理任务,shutdown()与shutdown(true)的完成结果相同。业务程序应按下一页的规则选择关闭语义。
常见错误
- 把
Auto当成性能自动优化:普通Auto不会偷偷改投无锁、实时或 GPU 后端;它只是安全的默认异步入口。 - 只提交,不保存 future:适合明确的 fire-and-forget 任务,但你失去返回值与异常传播路径。
- 把
submit_periodic()当实时任务:它是普通线程池的软周期调度;严格控制循环请使用后续的实时教程。 - 首次提交后再初始化:配置可能已经无法按预期生效;请先完成初始化。
下一步阅读
先阅读提交自己的函数与数据,学习如何传入自由函数、成员函数、参数和业务对象;然后由返回值与异常解释如何选择和补充失败观察路径。需要判断何时离开默认路径时,阅读执行模型与路由边界。