0
0
CppConceptBeginner · 4 min read

What is Thread Pool in C++: Explanation and Example

A thread pool in C++ is a collection of pre-created threads that efficiently manage multiple tasks by reusing threads instead of creating new ones each time. It helps improve performance by reducing the overhead of thread creation and destruction.
⚙️

How It Works

Imagine you have a team of workers ready to do tasks. Instead of hiring a new worker for every single job, you keep a fixed team that takes turns doing the work. This is how a thread pool works in C++. It creates a set number of threads at the start and keeps them alive, waiting for tasks.

When a new task comes, the thread pool assigns it to one of the free threads. Once the thread finishes the task, it goes back to the pool to wait for the next job. This way, the program avoids the time and resource cost of creating and destroying threads repeatedly.

This approach is especially useful when you have many small tasks that need to run concurrently, like handling multiple user requests or processing data in parallel.

💻

Example

This example shows a simple thread pool in C++ using the standard library. It creates a pool of threads that execute tasks from a queue.

cpp
#include <iostream>
#include <vector>
#include <thread>
#include <queue>
#include <functional>
#include <condition_variable>
#include <mutex>

class ThreadPool {
public:
    ThreadPool(size_t numThreads) : stop(false) {
        for (size_t i = 0; i < numThreads; ++i) {
            workers.emplace_back([this] {
                while (true) {
                    std::function<void()> task;
                    {
                        std::unique_lock<std::mutex> lock(this->queueMutex);
                        this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });
                        if (this->stop && this->tasks.empty())
                            return;
                        task = std::move(this->tasks.front());
                        this->tasks.pop();
                    }
                    task();
                }
            });
        }
    }

    template<class F>
    void enqueue(F&& f) {
        {
            std::unique_lock<std::mutex> lock(queueMutex);
            tasks.emplace(std::forward<F>(f));
        }
        condition.notify_one();
    }

    ~ThreadPool() {
        {
            std::unique_lock<std::mutex> lock(queueMutex);
            stop = true;
        }
        condition.notify_all();
        for (std::thread &worker : workers)
            worker.join();
    }

private:
    std::vector<std::thread> workers;
    std::queue<std::function<void()>> tasks;
    std::mutex queueMutex;
    std::condition_variable condition;
    bool stop;
};

int main() {
    ThreadPool pool(3); // 3 threads in the pool

    for (int i = 1; i <= 5; ++i) {
        pool.enqueue([i] {
            std::cout << "Task " << i << " is running on thread "
                      << std::this_thread::get_id() << std::endl;
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        });
    }

    std::this_thread::sleep_for(std::chrono::seconds(1)); // wait for tasks to finish
    return 0;
}
Output
Task 1 is running on thread 140703123456000 Task 2 is running on thread 140703114063296 Task 3 is running on thread 140703105670592 Task 4 is running on thread 140703123456000 Task 5 is running on thread 140703114063296
🎯

When to Use

Use a thread pool when you have many small or medium tasks that need to run concurrently and you want to avoid the cost of creating and destroying threads repeatedly. It is ideal for server applications handling multiple client requests, parallel data processing, or any program that benefits from running tasks in the background efficiently.

Thread pools help improve performance and resource management by limiting the number of active threads and reusing them, which reduces overhead and prevents your system from creating too many threads that could slow it down.

Key Points

  • A thread pool keeps a fixed number of threads ready to run tasks.
  • It improves performance by reusing threads instead of creating new ones.
  • Tasks are queued and assigned to threads when they become free.
  • Useful for handling many concurrent tasks efficiently.
  • C++ standard library does not have a built-in thread pool, so you often implement your own or use third-party libraries.

Key Takeaways

A thread pool manages a fixed set of threads to run multiple tasks efficiently.
It reduces overhead by reusing threads instead of creating and destroying them repeatedly.
Thread pools are ideal for programs with many concurrent small tasks or requests.
C++ requires custom or third-party thread pool implementations as it lacks a built-in one.
Using a thread pool improves resource management and application performance.