Advertisement
Guest User

Untitled

a guest
Jul 28th, 2013
294
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.24 KB | None | 0 0
  1. #ifndef _THREADPOOL_H_
  2. #define _THREADPOOL_H_
  3.  
  4. #include <functional>
  5. #include <thread>
  6. #include <queue>
  7. #include <mutex>
  8. #include <memory>
  9.  
  10. using std::function;
  11. using std::queue;
  12. using std::mutex;
  13. using std::thread;
  14. using std::shared_ptr;
  15. using std::vector;
  16.  
  17. template<class _T>
  18. struct AData
  19. {
  20.     AData():ready(false){}
  21.     volatile bool ready;
  22.     _T data;
  23. };
  24.  
  25. class ThreadPool
  26. {
  27. public:
  28.  
  29.     typedef function<void()> fn_type;
  30.  
  31.     class Worker
  32.     {    
  33.     public:
  34.         Worker()
  35.             :enabled(true),fqueue()
  36.             ,thread(&Worker::thread_fn, this)
  37.         {}
  38.         ~Worker()
  39.         {
  40.             enabled = false;
  41.             thread.join();
  42.         }  
  43.         void appendFn(fn_type fn)
  44.         {
  45.             mutex.lock();
  46.             fqueue.push(fn);
  47.             mutex.unlock();
  48.         }
  49.         queue<fn_type>  fqueue;
  50.     protected:
  51.         mutex           mutex;
  52.         thread          thread;
  53.         volatile bool   enabled;   
  54.  
  55.         void thread_fn()
  56.         {
  57.             while (enabled)
  58.             {
  59.                 if(!fqueue.empty())
  60.                 {
  61.                     mutex.lock();
  62.                     fn_type fn = fqueue.front();
  63.                     fqueue.pop();
  64.                     mutex.unlock();
  65.                     fn();
  66.                 }
  67.                 else
  68.                     std::this_thread::yield();
  69.             }
  70.         }
  71.     };
  72.  
  73.     typedef shared_ptr<Worker> worker_ptr;
  74.  
  75.     ThreadPool(size_t threads = 1)
  76.     {
  77.         if (threads==0)
  78.             threads=1;
  79.         for (size_t i=0; i<threads; i++)
  80.         {
  81.             worker_ptr pWorker(new Worker);
  82.             _workers.push_back(pWorker);
  83.         }
  84.     }
  85.  
  86.     ~ThreadPool()
  87.     {
  88.         _workers.clear();
  89.     }
  90.  
  91.     template<class _R, class _FN, class... _ARGS>
  92.     shared_ptr<AData<_R>> runAsync(_FN _fn, _ARGS... _args)
  93.     {
  94.         function<_R()> rfn = std::bind(_fn,_args...);  
  95.         shared_ptr<AData<_R>> pData(new AData<_R>());
  96.         fn_type fn = [=]()
  97.         {
  98.             pData->data = rfn();
  99.             pData->ready = true;
  100.         };
  101.         getFreeWorker()->appendFn(fn);
  102.         return pData;
  103.     }
  104.  
  105.     template<class _FN, class... _ARGS>
  106.     void runAsync(_FN _fn, _ARGS... _args)
  107.     {
  108.         getFreeWorker()->appendFn(std::bind(_fn,_args...));
  109.     }
  110.  
  111. protected:
  112.        
  113.     worker_ptr getFreeWorker()
  114.     {
  115.         worker_ptr pWorker = _workers[0];
  116.         size_t minTasks = pWorker->fqueue.size();              
  117.         for (auto &it : _workers)
  118.         {
  119.             if (it->fqueue.empty())
  120.                 return it;
  121.             else if (minTasks > it->fqueue.size())
  122.             {
  123.                 minTasks = it->fqueue.size();
  124.                 pWorker = it;
  125.             }
  126.         }
  127.         return pWorker;
  128.     }
  129.  
  130.     vector<worker_ptr> _workers;
  131.  
  132. };
  133.  
  134. #endif /*_THREADPOOL_H_*/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement