Your First Task
Goal
Use Executor::instance() to submit work returning 42, then retrieve the result and an exception through future.get().
Recommended approach
Use submit_auto(lambda). For ordinary finite work, Auto safely selects the default asynchronous executor. It returns a std::future: get() returns the value after success and rethrows a task exception on the calling thread. The first submission lazily initializes Executor with its default configuration.
This does not choose the fastest registered executor: an ordinary lambda never moves to GPU, lock-free, or realtime. For the exact intent-and-name matching rules of submit_auto, dispatch_auto, and start_worker, read how automatic routing matches a target.
#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;
}Full source: examples/tutorial/01_first_task.cpp.
./build/examples/tutorial/tutorial_01_first_taskExpected output
answer=42
task failed: expected tutorial failureWhy this matters
future.get()is both a result operation and an exception-observation boundary.get_last_routing_decision()explains why the default Facade selected its path; it is not a completion result.- Default configuration is appropriate for this minimal example.
- Configure thread counts, queue capacity, or monitoring with
initialize_ex()before the first submission. - The example ends with
shutdown(). Applications must choose their shutdown semantics at a real component boundary.
Common mistakes
- Submitting without retaining the future when you still need a return value or task exception.
- Treating
submit_periodic()as a real-time task; it is soft periodic scheduling on the ordinary pool.submit_auto(lambda)does not silently select real-time, lock-free, or GPU backends. - Configuring the singleton after the first submission has already initialized it.
Read submit functions and data next. It explains how to pass free functions, member functions, parameters, and business objects safely; return values and errors then covers failure observation. Read initialization and shutdown when you need explicit lifecycle control.