This is copied from my answer to another very similar post:
Start with maximum number of threads the system can support:
int num_threads = std::thread::hardware_concurrency();
For an efficient threadpool implementation, once threads are created according to num_threads, it’s better not to create new ones, or destroy old ones (by joining). There will be a performance penalty, an it might even make your application goe slower than the serial version.
Each C++11 thread should be running in their function with an infinite loop, constantly waiting for new tasks to grab and run.
Here is how to attach such a function to the thread pool:
int num_threads = std::thread::hardware_concurrency();
std::vector
for (int i = 0; i < num_threads; i++)
{
pool.push_back(std::thread(Infinite_loop_function));
}
The infinite loop function. This is a while (true) loop waiting for the task queue.
void Pool::Infinite_loop_function()
{
while (true)
{
std::unique_lock
condition.wait(lock, [this](){
return !queue.empty() || terminate_pool;
});
Job = queue.front();
queue.pop();
Job(); // function
}
};
Make a function to add job to your queue
void Pool::Add_Job(function
{
std::unique_lock
queue.push(New_Job);
condition.notify_one();
}
Bind an arbitrary function to your queue
Pool_Obj.Add_Job(std::bind(&Some_Class::Some_Method, &Some_object));
Once you integrate these ingredients, you have your own dynamic threading pool. These threads always run, waiting for job to do.
I apologize if there are some syntax errors, I typed these code and and I have a bad memory. Sorry that I cannot provide you the complete thread pool code, that would violate my job integrity.
Edit: to terminate the pool, call the shutdown() method:
Pool::shutdown()
{
std::unique_lock
terminate_pool = true; // use this flag in condition.wait
condition.notify_all(); // wake up all threads.
// Join all threads.
for(std::thread &th : threads)
{
th.join();
}
pool.clear();
stopped = true; // use this flag in destructor, if not set, call shutdown()
}
You can use C++ Thread Pool Library, https://github.com/vit-vit/ctpl.
Then the code your wrote can be replaced with the following
#include
int main (int argc, char *argv[]) {
ctpl::thread_pool p(2 /* two threads in the pool */);
int arr[4] = {0};
std::vector
for (int i = 0; i < 8; ++i) { // for 8 iterations,
for (int j = 0; j < 4; ++j) {
results[j] = p.push([&arr, j](int){ arr[j] +=2; });
}
for (int j = 0; j < 4; ++j) {
results[j].get();
}
arr[4] = std::min_element(arr, arr + 4);
}
}
You will get the desired number of threads and will not create and delete them over and over again on the iterations.