// // Copyright @ 2016 Hangzhou Topzen Ltd. // Author: Wu Jiubao (wujb@hztopzen.com) @ 2016-09 // #ifndef __THREADPOOL_H #define __THREADPOOL_H #include #include "Thread.h" #include "Semaphore.h" #include "BaseTypes.h" #include "Locks.h" namespace tzc { class CWorkerThread; class CJob; // thread pool, manage all threads class DECLDLL CThreadPool : public tzc::OSThread { friend class CWorkerThread; #ifdef THREADPOOL_SINGLETON private: CThreadPool(); virtual ~CThreadPool(); #else public: CThreadPool(); CThreadPool(TZ_Uint32 num); virtual ~CThreadPool(); #endif public: #ifdef THREADPOOL_SINGLETON static CThreadPool * GetInstance(void); static void DeleteInstance(void); #endif TZ_INT Initialize(); void SetMaxThreadNum(TZ_Uint32 maxNum); TZ_Uint32 GetMaxThreadNum(void); void SetLowIdleThreadNum(TZ_Uint32 minNum); TZ_Uint32 GetLowIdleThreadNum(void); void SetHighIdleThreadNum(TZ_Uint32 highNum); TZ_Uint32 GetHighIdleThreadNum(void); TZ_Uint32 GetIdleThreadNum(void); TZ_Uint32 GetAllThreadNum(void); TZ_Uint32 GetBusyThreadNum(void); void SetInitThreadNum(TZ_Uint32 initNum); TZ_Uint32 GetInitThreadNum(void); void TerminateAll(void); void PushJob(CJob * job); protected: virtual void Entry(); TZ_INT setJob2WorkerThread(CJob * job); CWorkerThread * getIdleThread(void); void appendToIdleList(CWorkerThread * jobthread); void moveToBusyList(CWorkerThread * idlethread); void moveToIdleList(CWorkerThread * busythread); void deleteIdleThread(TZ_Uint32 num); void createIdleThread(TZ_Uint32 num); private: #ifdef THREADPOOL_SINGLETON static CThreadPool * _instance; static tzc::Mutex _insMutex; #endif tzc::Mutex m_busyMutex; // used for operating m_busyList tzc::Mutex m_idleMutex; // used for operating m_idleList tzc::Mutex m_jobMutex; // used for getting idle thread to do job std::list m_threadList; // all threads in thread pool std::list m_busyList; // busy threads in thread pool std::list m_idleList; // idle threads in thread pool std::list m_jobList; TZ_Uint32 m_maxNum; // max number of thread TZ_Uint32 m_availLow; // the lowest available threads in thread pool TZ_Uint32 m_availHigh; // the highest available threads in thread pool TZ_Uint32 m_availNum; // current available threads in thread pool TZ_Uint32 m_initNum; // init number of thread TZ_Uint32 m_jobNum; // job number in the m_jobList }; inline void CThreadPool::SetMaxThreadNum(TZ_Uint32 maxNum) { m_maxNum = maxNum; } inline TZ_Uint32 CThreadPool::GetMaxThreadNum(void) { return m_maxNum; } inline void CThreadPool::SetLowIdleThreadNum(TZ_Uint32 minNum) { m_availLow = minNum; } inline TZ_Uint32 CThreadPool::GetLowIdleThreadNum(void) { return m_availLow; } inline void CThreadPool::SetHighIdleThreadNum(TZ_Uint32 highNum) { m_availHigh = highNum; } inline TZ_Uint32 CThreadPool::GetHighIdleThreadNum(void) { return m_availHigh; } inline TZ_Uint32 CThreadPool::GetIdleThreadNum(void) { return m_availNum; } inline TZ_Uint32 CThreadPool::GetAllThreadNum(void) { ScopedLock lock(m_idleMutex); return m_threadList.size(); } inline TZ_Uint32 CThreadPool::GetBusyThreadNum(void) { ScopedLock lock(m_busyMutex); return m_busyList.size(); } inline void CThreadPool::SetInitThreadNum(TZ_Uint32 initNum) { m_initNum = initNum; } inline TZ_Uint32 CThreadPool::GetInitThreadNum(void) { return m_initNum; } // work thread, all threads start to wait for job when be constructed class DECLDLL CWorkerThread : public tzc::OSThread { friend class CThreadPool; private: CWorkerThread(CThreadPool * thrPool); virtual ~CWorkerThread(); virtual void Entry(); void StartWork(CJob * job); void StopWork(void); private: CThreadPool * m_threadPool; CJob * m_job; TZ_BOOL m_bExit; tzc::Semaphore m_jobCond; }; // base class of Job, all concrete jobs should inherit it and implement the Run() class DECLDLL CJob { public: CJob(const std::string & jobName, void * jobData); virtual ~CJob(); TZ_Uint32 GetJobNo(void); TZ_BOOL ToDeleted(void); virtual void Run() = 0; protected: static TZ_Uint32 _jobNo; static tzc::Mutex _jobNoMutex; TZ_Uint32 m_jobNo; TZ_BOOL m_toDeleted; std::string m_jobName; void * m_jobData; }; } // namespace tzc #endif /*-----#ifndef _THREADPOOL_H-----*/