# cartographer/common/thread_pool.h ## Overview `ThreadPool` provides a simple task-based thread pool for parallel execution. Used by `MapBuilder` for background scan matching and optimization tasks. ## Class: `cartographer::common::ThreadPool` ### Construction ```cpp explicit ThreadPool(int num_threads); ~ThreadPool(); ``` - `num_threads` — Number of worker threads (0 = no background threads, tasks run synchronously) ### Task Submission ```cpp // Submit a task with no return value void Schedule(std::function task); // Submit a task with return value template std::future Schedule(std::function task); ``` ### Synchronization ```cpp // Wait for all scheduled tasks to complete void WaitForAllTasks(); ``` ### Queries ```cpp int num_threads() const; ``` ## Usage in Cartographer ### MapBuilder Integration ```cpp // In MapBuilder constructor MapBuilder::MapBuilder(const proto::MapBuilderOptions& options) : options_(options), thread_pool_(options.num_background_threads()) { // ... } // Scheduling scan matching thread_pool_.Schedule([this, trajectory_id, ...]() { // Run scan matching in background auto result = scan_matcher_->Match(...); // Post result back to main thread task_queue_.Push([this, result]() { ... }); }); ``` ### Typical Workflow ``` Main Thread Background Threads | | |--- Schedule(scan matching) -------->| | |--- Match() | |--- Optimize() |<-- Schedule(callback) --------------| |--- callback(result) --------------->| | | ``` ## Task Queue Cartographer uses a custom `TaskQueue` (in `internal/task_queue.h`) for thread-safe task passing between background threads and the main thread. ```cpp class TaskQueue { public: void Push(std::function task); std::function Pop(); // Blocks until task available }; ``` ## Thread Safety - `Schedule()` is thread-safe - `WaitForAllTasks()` blocks until all scheduled tasks complete - Tasks should not block indefinitely (use timeouts for external calls) ## Configuration From `map_builder.lua`: ```lua MAP_BUILDER = { num_background_threads = 4, -- Typical: num CPU cores - 1 } ``` ## Best Practices 1. **Keep tasks short** — Long-running tasks block threads 2. **Avoid locks in tasks** — Use task queue for main-thread communication 3. **Handle exceptions** — Uncaught exceptions in tasks terminate the program 4. **Limit queue depth** — Too many pending tasks = memory pressure ## See Also - [MapBuilder](../mapping/map_builder.md) — Uses ThreadPool - [LocalTrajectoryBuilder](../mapping/trajectory_builder_interface.md) — Schedules scan matching - [PoseGraph](../mapping/pose_graph_interface.md) — Schedules optimization