Thread pool in C++
C++11 through C++23 do not provide a standard thread
pool in the STL. You either build one (queue + worker
std::threads + std::mutex +
std::condition_variable) or use a library. C++26 adds
std::thread_pool. See
What is Thread Pool?.
1. Manual thread pool (standard C++11+)
Classic pattern: N worker threads loop, pulling callables from a shared queue. This is how most production pools work when you cannot add a dependency.
#include <iostream>
#include <thread>
#include <vector>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <future>
class ThreadPool {
public:
explicit ThreadPool(size_t n) : stop_(false) {
for (size_t i = 0; i < n; ++i) {
workers_.emplace_back([this] {
while (true) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(mutex_);
cv_.wait(lock, [this] { return stop_ || !tasks_.empty(); });
if (stop_ && tasks_.empty()) return;
task = std::move(tasks_.front());
tasks_.pop();
}
task();
}
});
}
}
template <class F>
void submit(F&& f) {
{
std::lock_guard<std::mutex> lock(mutex_);
tasks_.emplace(std::forward<F>(f));
}
cv_.notify_one();
}
~ThreadPool() {
{
std::lock_guard<std::mutex> lock(mutex_);
stop_ = true;
}
cv_.notify_all();
for (auto& t : workers_) t.join();
}
private:
std::vector<std::thread> workers_;
std::queue<std::function<void()>> tasks_;
std::mutex mutex_;
std::condition_variable cv_;
bool stop_;
};
int main() {
ThreadPool pool(4);
for (int i = 0; i < 10; ++i) {
pool.submit([i] { std::cout << "task " << i << "\n"; });
}
// pool destructor waits for workers
}
2. std::async — not a true pool
std::async(std::launch::async, ...) may spawn a new thread
per call — no reuse, no queue limit. Fine for a few tasks; not a thread
pool substitute at scale.
#include <future>
#include <iostream>
int main() {
auto fut = std::async(std::launch::async, [] {
return 42;
});
std::cout << fut.get() << "\n";
}
3. C++26 — std::thread_pool
The C++26 standard adds a built-in thread pool (P0443). Syntax may vary slightly by compiler; check your toolchain.
// C++26 (when available)
#include <thread_pool>
#include <iostream>
int main() {
std::thread_pool pool(4);
pool.submit([] { std::cout << "task on pool\n"; });
pool.wait(); // wait for submitted work
}
4. Third-party libraries
When you need a production pool today without writing your own:
- BS::thread_pool — single-header, drop-in pool
- Boost.Asio —
thread_poolexecutor - Intel oneTBB — task arena / parallel tasks
// BS::thread_pool example (header-only library)
#include "BS_thread_pool.hpp"
int main() {
BS::thread_pool pool(4);
for (int i = 0; i < 10; ++i)
pool.submit_task([i] { /* work */ });
pool.wait();
}