diff --git a/include/threadpool.h b/include/threadpool.h new file mode 100644 index 0000000..0645885 --- /dev/null +++ b/include/threadpool.h @@ -0,0 +1,41 @@ +#ifndef _THREADPOOL_H_ +#define _THREADPOOL_H_ + +#include +#include +#include +#include +#include +#include +#include + +class threadpool +{ +private: + std::size_t _concurrency; + std::queue> _queue; + std::mutex _mutex; + std::condition_variable _cv; + std::vector _workers; + bool _enabled; + +public: + threadpool(); + threadpool(std::size_t concurrency); + ~threadpool(); + + template std::future add_task(std::function func) + { + std::lock_guard lock(_mutex); + std::packaged_task pt(func); + std::future fut = pt.get_future(); + _queue.push([&pt]{ pt(); }); + _cv.notify_all(); + return fut; + } + +private: + void worker_func(); +}; + +#endif // _THREADPOOL_H_ diff --git a/msvc/cpputil/cpputil.vcxproj b/msvc/cpputil/cpputil.vcxproj index bcf3baa..40070fc 100644 --- a/msvc/cpputil/cpputil.vcxproj +++ b/msvc/cpputil/cpputil.vcxproj @@ -78,12 +78,14 @@ + + diff --git a/msvc/cpputil/cpputil.vcxproj.filters b/msvc/cpputil/cpputil.vcxproj.filters index 23af821..e94e4e2 100644 --- a/msvc/cpputil/cpputil.vcxproj.filters +++ b/msvc/cpputil/cpputil.vcxproj.filters @@ -30,6 +30,9 @@ Source Files + + Source Files + @@ -44,5 +47,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/src/threadpool.cpp b/src/threadpool.cpp new file mode 100644 index 0000000..f58cb22 --- /dev/null +++ b/src/threadpool.cpp @@ -0,0 +1,42 @@ +#include "threadpool.h" + +threadpool::threadpool() : threadpool(std::thread::hardware_concurrency()) +{ +} + +threadpool::threadpool(std::size_t concurrency) : _concurrency(concurrency), _enabled(true) +{ + for (std::size_t i = 0; i < _concurrency; ++i) + { + _workers.push_back(std::thread(&threadpool::worker_func, this)); + } +} + +threadpool::~threadpool() +{ + _enabled = false; + _cv.notify_all(); + for (std::size_t i = 0; i < _workers.size(); ++i) + { + _workers[i].join(); + } +} + +void threadpool::worker_func() +{ + while (_enabled) + { + std::unique_lock lock(_mutex); + _cv.wait(lock, [this] { return (!_queue.empty() || !_enabled); }); + + if (_queue.empty() && !_enabled) + return; + + auto func = _queue.front(); + _queue.pop(); + + lock.unlock(); + + func(); + } +}