class mrpt::WorkerThreadsPool
Overview
A simple and efficient thread pool for parallel task execution.
This class manages a fixed number of worker threads that remain blocked waiting for jobs to be assigned via enqueue(). The enqueue() method accepts any callable object (function, lambda, functor) with arbitrary parameters and returns a std::future<ReturnType> that can be used to:
Wait for task completion
Retrieve the function’s return value
Catch any exceptions thrown by the task
When more tasks are assigned than available free threads, two policies exist:
POLICY_FIFO: All jobs are enqueued and executed in order (default)
POLICY_DROP_OLD: Older pending jobs are discarded when the queue exceeds the thread count. Note: running jobs are never aborted.
All public methods are thread-safe and can be called concurrently.
mrpt::WorkerThreadsPool pool(4); // 4 worker threads // Enqueue a task and get a future auto future = pool.enqueue([](int x) { return x * 2; }, 21); // Wait for result int result = future.get(); // result == 42
Partly based on: https://github.com/progschj/ThreadPool (ZLib license)
See also:
std::async, std::thread
#include <mrpt/core/WorkerThreadsPool.h> class WorkerThreadsPool { public: // enums enum queue_policy_t; // construction WorkerThreadsPool(); WorkerThreadsPool( std::size_t num_threads, queue_policy_t policy = POLICY_FIFO, const std::string& threadsName = "WorkerThreadsPool" ); WorkerThreadsPool(const WorkerThreadsPool&); WorkerThreadsPool(WorkerThreadsPool&&); // methods WorkerThreadsPool& operator = (const WorkerThreadsPool&); WorkerThreadsPool& operator = (WorkerThreadsPool&&); void resize(std::size_t num_threads); std::size_t size() const; void clear(); template <class F, class... Args> auto enqueue(F&& f, Args&&... args); std::size_t pendingTasks() const; void name(const std::string& name); std::string name() const; };
Construction
WorkerThreadsPool()
Default constructor.
Creates a pool with no threads.
Call resize() to add worker threads before enqueuing tasks.
WorkerThreadsPool( std::size_t num_threads, queue_policy_t policy = POLICY_FIFO, const std::string& threadsName = "WorkerThreadsPool" )
Constructs a thread pool with the specified number of threads.
Thread names will be formatted as “${threadsName}[i]” where i is the thread index (0-based).
Parameters:
num_threads |
Number of worker threads to create. Should be > 0. |
policy |
Queue overflow policy (default: POLICY_FIFO) |
threadsName |
Base name for worker threads (for debugging) |
Methods
void resize(std::size_t num_threads)
Adds worker threads to the pool.
This method adds threads to the existing pool. To replace all threads, call clear() first.
Parameters:
num_threads |
Number of threads to add. |
std::size_t size() const
Returns the number of worker threads in the pool.
Returns:
Current thread count.
void clear()
Stops all worker threads and clears the pool.
This method:
Signals all threads to stop
Wakes up all waiting threads
Waits for all threads to finish (joins them)
Clears the thread container
Any pending tasks that haven’t started will be discarded. A warning is printed to stderr if tasks are discarded.
template <class F, class... Args> auto enqueue(F&& f, Args&&... args)
Enqueues a task for execution by a worker thread.
The returned future must not be discarded ([[nodiscard]]). If you don’t need the result, store the future and let it destruct naturally, or call future.wait() to ensure completion.
auto f1 = pool.enqueue([]{ return 42; }); auto f2 = pool.enqueue([](int a, int b){ return a + b; }, 1, 2); std::cout << f1.get() << ", " << f2.get(); // "42, 3"
Parameters:
F |
Callable type (function, lambda, functor, etc.) |
Args |
Argument types for the callable |
f |
The callable to execute |
args |
Arguments to pass to the callable |
std::runtime_error |
if called after clear() or during destruction. |
Returns:
std::future that will hold the result of f(args…). Use future.get() to wait for and retrieve the result. Any exception thrown by f will be stored and re-thrown when get() is called.
std::size_t pendingTasks() const
Returns the number of tasks waiting in the queue.
This does NOT include tasks currently being executed by worker threads.
Returns:
Number of pending (queued but not started) tasks.
void name(const std::string& name)
Sets the base name for threads in this pool.
Thread names are visible in debuggers, profilers, and system tools. Individual threads will be named “${name}[i]” where i is the index.
New in MRPT 2.1.5
pool.name("MyPool"); // Threads will be named: MyPool[0], MyPool[1], ...
Parameters:
name |
Base name for the threads (max ~15 chars on Linux) |
std::string name() const
Returns the base name of threads in this pool.
Returns:
The thread name prefix set via name() or constructor.