Some reformatting and changed packaged_task to function

This commit is contained in:
Samer Afach 2019-06-17 14:38:29 +00:00
parent 6511898193
commit 11332c8cf3
3 changed files with 199 additions and 188 deletions

View File

@ -14,14 +14,15 @@ it. Using this library is your own responsibility
#ifndef THREADPOOL_H #ifndef THREADPOOL_H
#define THREADPOOL_H #define THREADPOOL_H
#include <condition_variable>
#include <deque> #include <deque>
#include <functional> #include <functional>
#include <mutex> #include <mutex>
#include <thread> #include <thread>
#include <vector> #include <vector>
#include <condition_variable>
class ThreadPool { class ThreadPool
{
long numOfThreads; long numOfThreads;
std::deque<std::function<void()>> _tasks; std::deque<std::function<void()>> _tasks;
std::mutex _queueLock; std::mutex _queueLock;
@ -41,12 +42,12 @@ public:
inline ~ThreadPool(); inline ~ThreadPool();
inline void push(const std::function<void()>& task); inline void push(const std::function<void()>& task);
inline void push(std::function<void()>&& task); inline void push(std::function<void()>&& task);
inline void inline void start(const long NumOfThreads = std::thread::hardware_concurrency());
start(const long NumOfThreads = std::thread::hardware_concurrency());
inline void finish(); inline void finish();
}; };
void ThreadPool::thread_worker() { void ThreadPool::thread_worker()
{
while (true) { while (true) {
std::unique_lock<decltype(_queueLock)> lg(_queueLock); std::unique_lock<decltype(_queueLock)> lg(_queueLock);
while (_tasks.empty() && !conclude_work) { while (_tasks.empty() && !conclude_work) {
@ -67,7 +68,8 @@ void ThreadPool::thread_worker() {
} }
} }
void ThreadPool::join_all() { void ThreadPool::join_all()
{
for (long i = 0; i < static_cast<long>(_threads.size()); i++) { for (long i = 0; i < static_cast<long>(_threads.size()); i++) {
if (_threads[i].joinable()) if (_threads[i].joinable())
_threads[i].join(); _threads[i].join();
@ -78,19 +80,22 @@ ThreadPool::ThreadPool() {}
ThreadPool::~ThreadPool() { this->finish(); } ThreadPool::~ThreadPool() { this->finish(); }
void ThreadPool::push(const std::function<void()> &task) { void ThreadPool::push(const std::function<void()>& task)
{
std::unique_lock<decltype(_queueLock)> lg(_queueLock); std::unique_lock<decltype(_queueLock)> lg(_queueLock);
_tasks.push_back(task); _tasks.push_back(task);
_queueCond.notify_one(); _queueCond.notify_one();
} }
void ThreadPool::push(std::function<void ()>&& task) { void ThreadPool::push(std::function<void()>&& task)
{
std::unique_lock<decltype(_queueLock)> lg(_queueLock); std::unique_lock<decltype(_queueLock)> lg(_queueLock);
_tasks.push_back(std::move(task)); _tasks.push_back(std::move(task));
_queueCond.notify_one(); _queueCond.notify_one();
} }
void ThreadPool::start(const long NumOfThreads) { void ThreadPool::start(const long NumOfThreads)
{
if (!started_already) if (!started_already)
started_already = true; started_already = true;
else else
@ -98,13 +103,13 @@ void ThreadPool::start(const long NumOfThreads) {
numOfThreads = NumOfThreads; numOfThreads = NumOfThreads;
_threads.reserve(numOfThreads); _threads.reserve(numOfThreads);
for (long i = 0; i < numOfThreads; i++) { for (long i = 0; i < numOfThreads; i++) {
_threads.push_back( _threads.push_back(std::thread(std::bind(&ThreadPool::thread_worker, this)));
std::thread(std::bind(&ThreadPool::thread_worker, this)));
num_of_threads_running++; num_of_threads_running++;
} }
} }
void ThreadPool::finish() { void ThreadPool::finish()
{
std::unique_lock<decltype(_queueLock)> lg(_queueLock); std::unique_lock<decltype(_queueLock)> lg(_queueLock);
conclude_work = true; conclude_work = true;
_queueCond.notify_all(); _queueCond.notify_all();

View File

@ -1,8 +1,10 @@
#include <future>
#include <iostream> #include <iostream>
#include "include/ThreadPool.h" #include "include/ThreadPool.h"
void SumZeroToNumber(long &num) { void SumZeroToNumber(long& num)
{
long val = 0; long val = 0;
for (long i = 0; i <= static_cast<long>(num); i++) { for (long i = 0; i <= static_cast<long>(num); i++) {
val += i; val += i;
@ -10,7 +12,8 @@ void SumZeroToNumber(long &num) {
num = val; num = val;
} }
int main() { int main()
{
for (int tries = 0; tries < 10; tries++) { for (int tries = 0; tries < 10; tries++) {
std::cout << "Try number: " << tries + 1 << "... "; std::cout << "Try number: " << tries + 1 << "... ";
@ -29,12 +32,15 @@ int main() {
// unchanged // unchanged
pool.push(std::bind(SumZeroToNumber, std::ref(numsResults[i]))); pool.push(std::bind(SumZeroToNumber, std::ref(numsResults[i])));
} }
long num = 10;
std::function<void()> task(std::bind(SumZeroToNumber, std::ref(num)));
pool.push(std::move(task));
// std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // std::this_thread::sleep_for(std::chrono::milliseconds(1000));
pool.finish(); pool.finish();
} catch (std::exception& ex) { } catch (std::exception& ex) {
std::cout std::cout << "An exception was thrown while processing data. Exception says: " << ex.what()
<< "An exception was thrown while processing data. Exception says: " << std::endl;
<< ex.what() << std::endl;
std::exit(1); std::exit(1);
} }
// test results sequentially // test results sequentially
@ -42,8 +48,8 @@ int main() {
SumZeroToNumber(numsSequentialResults[i]); SumZeroToNumber(numsSequentialResults[i]);
if (numsSequentialResults[i] != numsResults[i]) { if (numsSequentialResults[i] != numsResults[i]) {
std::cout << "failed." << std::endl; std::cout << "failed." << std::endl;
std::cout << "Comparing " << numsSequentialResults[i] << " with " std::cout << "Comparing " << numsSequentialResults[i] << " with " << numsResults[i]
<< numsResults[i] << " failed." << std::endl; << " failed." << std::endl;
throw std::runtime_error("Results didn't match!"); throw std::runtime_error("Results didn't match!");
} }
} }