Updated June 23, 2023
Definition of C++ Thread Pool
In C++, the thread pool actively utilizes a fixed number of threads to execute multiple tasks concurrently. When there is a need for concurrent task execution, the thread pool ensures that the available threads are effectively used. Pending tasks will remain in the queue, waiting for a thread to get free. In C++, there is no specific library for thread pool, but it provides various methods in the API which the programmer can use and create one according to the requirements.
Syntax:
Below given is the basic syntax for using the C++ thread pool:
using namespace std;
// initializing the number of threads
int count_threads = thread: : hardware_concurrency();
int main()
{
thread_pool pool;
// queuing the work/ task to thread pool queue and store the future
auto res = pool.enqueue([](int x) { return x; }, 42);
//printing the output on console
cout << res.get() << endl;
}
In the above syntax,
- thread: hardware_concurrency(): It basically initializes the fixed number of threads that will work on the desired task.
- Pool.enqueue: It will enqueue the task request in the pool, which needs to be processed.
- res.get(): It is used to get the result from the future.
How Thread Pools Works in C++?
It is nice to work with the thread pools when we have many tasks, and we want them to execute parallelly. It reduces the overhead of the creation of threads every time, and too much of threads reduce the overall speed of the system. No specific library in C++ provides the thread pool, so the programmer must create it independently, depending on the requirements.
Below given is the step-by-step procedure of the working of thread in the thread pool in C++ :
1. The ThreadPool class is typically initialized with a fixed number of worker threads, which can be determined using the thread::hardware_concurrency() function.
2. When a new task arrives, it is first put in the queue of pending work, and the following steps are performed:
- It is first checked whether the thread in the thread pool is free or not.
- It then takes off the work from the task queue to perform the desired task.
- Once the thread performs the desired task, it again waits on the condition variable to show its state.
3. In a thread pool, objects are destroyed only when the programmer calls the destructor of the thread pool class.
Examples
One can implement the thread pool using the C++ APIs according to the requirements. But there are various challenges that the user/programmer faces while designing it. When working with thread pools in C++, there are several considerations for achieving efficient performance. Here are some of the techniques and factors to consider:
One of the simplest implementations of the thread pool is given below:
#include <iostream>
#include <cstdlib>
#include <thread>
#include create_pool.h
using namespace std;
#define trace(x)
// function to define the number of threads
auto int num_threads = thread::hardware_concurrency();
//checking condition of the number of threads available
// if the number of threads is 0
if(num_threads == 0)
{
num_threads =1;
}
const int total_task = 20000;
//main logic inside the main function with 2 arguments
int main(int argc, char** argv)
{
srand((unsigned int)time(NULL));
//creating a thread pool
thread_pool p;
//enqueue function used to queue the request that needs to be processed by
//thread pool and retrieving the output in 'output' variable
auto output = p.enqueue_task([](int x) { return x; }, 0xFF);
output.get();
//processing the request
for(int x = 1; x <= num_threads; x++)
p.enqueue_work([](int thread_number) {
int work_out = 0;
int work = total_task + (rand() % (total_task));
trace("Thread " << thread_number << "is going to start " << work );
for(int y = 0; y < work; y++)
work_out += rand();
trace("Execution of " << thread_number << " is ended");
}, x);
return 1;
}
Explanation:
The provided code performs the following steps:
It begins by creating threads using the thread::hardware_concurrency() function. To retrieve specific data from the output variable, the code employs the get() function. Subsequently, the code proceeds to process thread requests one at a time within a for loop. During this process, the console displays intermediate processing steps and the end result, aiding in the comprehension of the flow. One needs to implement many things while working in the real application checking various conditions. One can also add the mutex, which is listening from another application like database, disk, etc. One needs to be at the expert level and understand all the in-depth working of threads and the basic functions of C++ and their implementation before working on it.
Conclusion
The above description clearly explains what a C++ thread pool is and how it can be used in a program. Thread pools are important to use in an application as it becomes easy and efficient to use the threads. Moreover, it does not keep the system overloaded, as the user/ programmer can limit the number of threads and the tasks assigned to them. Tasks will remain in the queue and execute once the thread becomes free.
Recommended Articles
This is a guide to C++ Thread Pool. Here we discuss the Definition of a C++ Thread Pool with How Thread Pools Work in C++ with programming examples. You may also have a look at the following articles to learn more –