Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef _THREADPOOL_H_
- #define _THREADPOOL_H_
- #include <functional>
- #include <thread>
- #include <queue>
- #include <mutex>
- #include <memory>
- using std::function;
- using std::queue;
- using std::mutex;
- using std::thread;
- using std::shared_ptr;
- using std::vector;
- template<class _T>
- struct AData
- {
- AData():ready(false){}
- volatile bool ready;
- _T data;
- };
- class ThreadPool
- {
- public:
- typedef function<void()> fn_type;
- class Worker
- {
- public:
- Worker()
- :enabled(true),fqueue()
- ,thread(&Worker::thread_fn, this)
- {}
- ~Worker()
- {
- enabled = false;
- thread.join();
- }
- void appendFn(fn_type fn)
- {
- mutex.lock();
- fqueue.push(fn);
- mutex.unlock();
- }
- queue<fn_type> fqueue;
- protected:
- mutex mutex;
- thread thread;
- volatile bool enabled;
- void thread_fn()
- {
- while (enabled)
- {
- if(!fqueue.empty())
- {
- mutex.lock();
- fn_type fn = fqueue.front();
- fqueue.pop();
- mutex.unlock();
- fn();
- }
- else
- std::this_thread::yield();
- }
- }
- };
- typedef shared_ptr<Worker> worker_ptr;
- ThreadPool(size_t threads = 1)
- {
- if (threads==0)
- threads=1;
- for (size_t i=0; i<threads; i++)
- {
- worker_ptr pWorker(new Worker);
- _workers.push_back(pWorker);
- }
- }
- ~ThreadPool()
- {
- _workers.clear();
- }
- template<class _R, class _FN, class... _ARGS>
- shared_ptr<AData<_R>> runAsync(_FN _fn, _ARGS... _args)
- {
- function<_R()> rfn = std::bind(_fn,_args...);
- shared_ptr<AData<_R>> pData(new AData<_R>());
- fn_type fn = [=]()
- {
- pData->data = rfn();
- pData->ready = true;
- };
- getFreeWorker()->appendFn(fn);
- return pData;
- }
- template<class _FN, class... _ARGS>
- void runAsync(_FN _fn, _ARGS... _args)
- {
- getFreeWorker()->appendFn(std::bind(_fn,_args...));
- }
- protected:
- worker_ptr getFreeWorker()
- {
- worker_ptr pWorker = _workers[0];
- size_t minTasks = pWorker->fqueue.size();
- for (auto &it : _workers)
- {
- if (it->fqueue.empty())
- return it;
- else if (minTasks > it->fqueue.size())
- {
- minTasks = it->fqueue.size();
- pWorker = it;
- }
- }
- return pWorker;
- }
- vector<worker_ptr> _workers;
- };
- #endif /*_THREADPOOL_H_*/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement