From f8a53f01515d9213ff44dfd363a4cce501ef8e75 Mon Sep 17 00:00:00 2001 From: misdake Date: Fri, 13 Jan 2017 11:35:39 +0800 Subject: [PATCH 1/2] threadCount specified by constructor. --- README.md | 14 +++++++------- ThreadPool.h | 23 ++++++++++++----------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 36ee1f0..32a3c24 100644 --- a/README.md +++ b/README.md @@ -8,15 +8,14 @@ I needed a Thread Pool for something I was writing, and I didn't see any that I Public Domain. If my licensing is wrong, please let me know. Use at your own risk for whatever you want. Feel free to change the namespaces as well. Apparently licensing is hard and complicated. If your country doesn't have a public domain, feel free to say you found this on the side of the road. ## Overview -`ThreadPool` is a super simple class that manages threads and jobs. `ThreadCount` threads are created at object instantiation time, and persist until the `ThreadPool` object is destroyed. You cannot change the thread count. A later version may allow you to set the thread count through the constructor rather than as a template parameter, but it's not something I care to do at the moment. Jobs are functions with no parameters or return values. This decision was to make it as generic as possible so it could be integrated into a variety of projects. If you can't get your job to work with those constraints, you're doing something wrong, or you need to roll your own ThreadPool. But you're probably making things overly complicated. +`ThreadPool` is a super simple class that manages threads and jobs. `threadCount` threads are created at object instantiation time, and persist until the `ThreadPool` object is destroyed. You cannot change the thread count. Jobs are functions with no parameters or return values. This decision was to make it as generic as possible so it could be integrated into a variety of projects. If you can't get your job to work with those constraints, you're doing something wrong, or you need to roll your own ThreadPool. But you're probably making things overly complicated. Below is a quick overview, but ThreadPool.h is documented, so just read that. It's less than 200 lines with comments. ```c++ -template class ThreadPool { public: - ThreadPool(); + ThreadPool( unsigned threadCount = std::thread::hardware_concurrency() ); ~ThreadPool(); void AddJob( std::function ); unsigned Size() const; @@ -36,7 +35,8 @@ public: int main() { using nbsdx::concurrent::ThreadPool; - ThreadPool pool; // Defaults to 10 threads. + // 10 threads for 100 jobs + ThreadPool pool(10); int JOB_COUNT = 100; for( int i = 0; i < JOB_COUNT; ++i ) @@ -51,12 +51,12 @@ int main() { Convience Function for running a list of jobs in a pool, assuming the type being iterated is of `std::function`: ```c++ -template +template void RunInPool( Iter begin, Iter end ) { - ThreadPool pool; + ThreadPool pool; for( ; begin != end; begin = std::next( begin ) ) pool.AddJob( *begin ); pool.JoinAll(); } ``` -It's worth nothing that the `pool.JoinAll();` is optional in this example, since `JoinAll` is invoked upon object deconstruction. +It's worth noting that the `pool.JoinAll();` is optional in this example, since `JoinAll` is invoked upon object deconstruction. diff --git a/ThreadPool.h b/ThreadPool.h index 730dd60..6da57d1 100644 --- a/ThreadPool.h +++ b/ThreadPool.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include @@ -13,15 +13,15 @@ namespace nbsdx { namespace concurrent { /** - * Simple ThreadPool that creates `ThreadCount` threads upon its creation, - * and pulls from a queue to get new jobs. The default is 10 threads. + * Simple ThreadPool that creates `threadCount` threads upon its creation, + * and pulls from a queue to get new jobs. The default is CPU thread count. * * This class requires a number of c++11 features be present in your compiler. */ -template class ThreadPool { - - std::array threads; + + unsigned threadCount; + std::vector threads; std::list> queue; std::atomic_int jobs_left; @@ -68,13 +68,14 @@ class ThreadPool { } public: - ThreadPool() - : jobs_left( 0 ) + ThreadPool(unsigned threadCount = std::thread::hardware_concurrency()) + : threadCount( threadCount ) + , jobs_left( 0 ) , bailout( false ) , finished( false ) { - for( unsigned i = 0; i < ThreadCount; ++i ) - threads[ i ] = std::move( std::thread( [this,i]{ this->Task(); } ) ); + for( unsigned i = 0; i < threadCount; ++i ) + threads.push_back( std::thread( [this,i]{ this->Task(); } ) ); } /** @@ -88,7 +89,7 @@ class ThreadPool { * Get the number of threads in this pool */ inline unsigned Size() const { - return ThreadCount; + return threadCount; } /** From a30e6717682746d4766bd4be0fe8d99a31e9a05b Mon Sep 17 00:00:00 2001 From: misdake Date: Tue, 12 Dec 2017 11:39:37 +0800 Subject: [PATCH 2/2] construct std::thread in-place. --- ThreadPool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThreadPool.h b/ThreadPool.h index 6da57d1..c17f12b 100644 --- a/ThreadPool.h +++ b/ThreadPool.h @@ -75,7 +75,7 @@ class ThreadPool { , finished( false ) { for( unsigned i = 0; i < threadCount; ++i ) - threads.push_back( std::thread( [this,i]{ this->Task(); } ) ); + threads.emplace_back( [this,i]{ this->Task(); } ); } /**