In C++03 I used pthread with a self-built thread pool that always kept a couple of threads running (since pthread_create
is slow), this way I was able to launch threads for small tasks without thinking about performance issues.
Now, in C++11 we have std::thread
. I guess the standard doesn't say anything about the specific implementation, so my question is about the standard library implementations. Are they generally opting for a pooled approach where constructing std::thread
s is cheap (and e.g. doesn't call pthread_create
on posix), or will std::thread
just be a wrapper?
In other words, is a thread pool still recommended in C++11, or should I just create a std::thread
whenever I need one and leave performance up to the standard library?
Threadpool in C++ is basically a pool having a fixed number of threads used when we want to work multiple tasks together (run multiple threads concurrently). This thread sits idle in the thread pool when there are no tasks and when a task arrives, it is sent to the thread pool and gets assigned to the thread.
A thread pool is a managed collection of threads that are available to perform tasks. Thread pools usually provide: Improved performance when executing large numbers of tasks due to reduced per-task invocation overhead. A means of bounding the resources, including threads, consumed when executing a collection of tasks.
For now, we know that if no policy is specified, then std::async launches a callable function in a separate thread. However, the C++ standard does not specify whether the thread is a new one or reused from a thread pool. Let us see how each of the three implementations launches a callable function.
A thread pool is a collection of threads which are assigned to perform uniformed tasks. The advantages of using thread pool pattern is that you can define how many threads is allowed to execute simultaneously.
Generally, std::thread
should be a minimal wrapper around underlying system primitive. For example, if you're on pthread
platform, you can test with the following program that no matter how many threads you create, they are all created with unique pthread_t
ids (which implies they're created on the fly and not borrowed from a thread pool):
#include <assert.h> #include <mutex> #include <set> #include <thread> #include <vector> #include <pthread.h> int main() { std::vector<std::thread> workers; std::set<long long> thread_ids; std::mutex m; const int n = 1024; for (int i = 0; i < n; ++i) { workers.push_back(std::thread([&] { std::lock_guard<std::mutex> lock(m); thread_ids.insert(pthread_self()); })); } for (auto& worker : workers) { worker.join(); } assert(thread_ids.size() == n); return 0; }
So thread pools still make perfect sense. That said, I've seen a video where C++ committee members discussed thread pools with regard to std::async
(IIRC), but I can't find it right now.
A std::thread
is a thread of execution. Period. Where it comes from, how it gets there, whether there is some pool of "actual" threads, etc, is all irrelevant to the standard. As long as it acts like a thread, it could be a std::thread
.
Now, odds are good that std::thread
is a real-life OS thread, not something pulled from a thread pool or whatever. But C++11 does theoretically allow a std::thread
to be implemented as a something pulled from a pool.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With