diff --git a/README.md b/README.md index c2f143a..8bd79cc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ # TinyThreadPool -C++11 tiny thread pool +C++17 tiny thread pool diff --git a/TinyThreadPool.h b/TinyThreadPool.h index 6cad804..601db3a 100644 --- a/TinyThreadPool.h +++ b/TinyThreadPool.h @@ -1,20 +1,22 @@ #ifndef THREAD_POOL_H #define THREAD_POOL_H -#include -#include -#include -#include -#include -#include -class TinyThreadPool { +// Changes in 2023: Changed 'result_of' to 'invoke_result_t' as it is not a member of 'std' in C++17 + +#include +#include +#include +#include +#include +#include +class TinyThreadPool { public: TinyThreadPool(size_t); - template - auto enqueue(F&& f, Args&& ... args) - ->std::future::type>; - ~TinyThreadPool(); + template + auto enqueue(F&& f, Args&&... args) -> std::future>; + ~TinyThreadPool(); + private: std::vector workers; std::queue> tasks; @@ -24,61 +26,52 @@ class TinyThreadPool { }; inline TinyThreadPool::TinyThreadPool(size_t threads) : stop(false) { - - for(size_t i = 0; i < threads; i++) { - - workers.emplace_back( - [this] - { - for(;;) { - std::function tasks; - { - std::unique_lock lock(this->queue_mutex); - this->condition.wait(lock, - [this]{ return this->stop || !this->tasks.empty();}); - if(this->stop && this->tasks.empty()) { - return; - } - tasks = std::move(this->tasks.front()); - this->tasks.pop(); + for (size_t i = 0; i < threads; i++) { + workers.emplace_back([this] { + for (;;) { + std::function task; + { + std::unique_lock lock(this->queue_mutex); + this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); }); + if (this->stop && this->tasks.empty()) { + return; } - tasks(); + task = std::move(this->tasks.front()); + this->tasks.pop(); } + task(); } - ); - } + }); + } } -template -auto TinyThreadPool::enqueue(F&& f, Args&&... args) - -> std::future::type> -{ - using return_type = typename std::result_of::type; - auto task = std::make_shared >( - std::bind(std::forward(f), std::forward(args) ...) - ); +template +auto TinyThreadPool::enqueue(F&& f, Args&&... args) -> std::future> { + using return_type = std::invoke_result_t; + + auto task = std::make_shared>(std::bind(std::forward(f), std::forward(args)...)); std::future res = task->get_future(); { std::unique_lock lock(queue_mutex); - if(stop) { - throw std::runtime_error("enqueue on stop ThreadPool"); + if (stop) { + throw std::runtime_error("enqueue on stopped ThreadPool"); } - tasks.emplace([task](){(*task)();}); + tasks.emplace([task] { (*task)(); }); } condition.notify_one(); return res; } - inline TinyThreadPool::~TinyThreadPool() { { std::unique_lock lock(queue_mutex); stop = true; } condition.notify_all(); - for(std::thread &worker : workers) { + for (std::thread& worker : workers) { worker.join(); } } -#endif \ No newline at end of file + +#endif