commit 4cc2dd62760fb3fa9e6899e40e0ffa57bb023f09 Author: kiritow <1362050620@qq.com> Date: Thu Nov 9 14:34:33 2017 +0800 Initial Commit diff --git a/ThreadPool.cpp b/ThreadPool.cpp new file mode 100644 index 0000000..254948c --- /dev/null +++ b/ThreadPool.cpp @@ -0,0 +1,143 @@ +#include "thread_pool.h" +using namespace std; + +void _global_thread_worker_main(ThreadWorkerData* ptdd) +{ + unique_lock ulk(ptdd->m); + while(ptdd->running) + { + ptdd->started=true; + ptdd->func(); + ptdd->finished=true; + ptdd->cond.wait(ulk); /// wait for new work. (will unlock ptdd->m while waiting...) + } +} + +ThreadPool::ThreadPool(int n) : left(0),busy(0),total(n) +{ + +} + +ThreadPool::~ThreadPool() +{ + for(int i=0;iget_id()<m.lock(); + if(dvec[i]->finished) + { + dvec[i]->m.unlock(); + break; + } + else + { + dvec[i]->m.unlock(); + this_thread::sleep_for(chrono::seconds(1)); + } + } + + dvec[i]->running=false; + /// notify it + dvec[i]->cond.notify_all(); + /// wait for it finish. + tvec[i]->join(); + /// release resource + delete dvec[i]; + dvec[i]=nullptr; + delete tvec[i]; + tvec[i]=nullptr; + } +} + +int ThreadPool::start(const function& func) +{ + if(left>0) + { + bool done=false; + int idx=-1; + + for(int i=0;im.try_lock()) + { + /// Failed to lock. + continue; + } + if(dvec[i]->finished) + { + /// Found a finished work! Now we reuse it. + dvec[i]->func=func; + dvec[i]->started=false; + dvec[i]->finished=false; + dvec[i]->running=true; + dvec[i]->cond.notify_all(); + + done=true; + idx=i; + + dvec[i]->m.unlock(); + break; + } + else + { + dvec[i]->m.unlock(); + } + } + + if(done) + { + left--; + busy++; + return idx; + } + else + { + return -2; + } + } + else + { + if(busyfunc=func; + ptdd->started=false; + ptdd->finished=false; + ptdd->running=true; + dvec.push_back(ptdd); + + thread* t=new thread(_global_thread_worker_main,ptdd); + tvec.push_back(t); + + busy++; + + return tvec.size()-1; + } + else + { + /// Check if we can reuse finished thread + for(int i=0;im.try_lock()) + { + /// Failed to lock. continue. + continue; + } + if(dvec[i]->finished) + { + left++; + busy--; + } + dvec[i]->m.unlock(); + } + + if(left>0) return start(func); + else return -1; + } + } +} diff --git a/ThreadPool.h b/ThreadPool.h new file mode 100644 index 0000000..f354504 --- /dev/null +++ b/ThreadPool.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include +#include +#include +#include + +struct ThreadWorkerData +{ + std::function func; + std::mutex m; + std::condition_variable cond; + bool started; + bool finished; + bool running; +}; + +void _global_thread_worker_main(ThreadWorkerData* ptdd); + + +class ThreadPool +{ +public: + ThreadPool(int n); + ~ThreadPool(); + + int start(const std::function& func); +private: + std::vector dvec; + std::vector tvec; + int left; + int busy; + int total; +};