文章的主要框架是参考这篇文档的,http://jacky-dai.iteye.com/blog/1090285,

关于作者

张中庆,西安交通大学软件所,在读硕士,目前研究方向为分布式网络与移动中间件,对Linux极其爱好,可以通过flydish1234@sina.com.cn与我联系

其实看了好多类似的,都是没有完整的实现,自己花了点时间把这个程序梳理了一下,写了个测试程序,目前可以跑通。

[html] view plaincopy
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <assert.h>
  6. #include <Windows.h>
  7. #include <functional>
  8. #include <process.h>
  9. using namespace std;
  10. class CThread;
  11. //锁的基类
  12. class CLockObject
  13. {
  14. public:
  15. virtual BOOL Lock() = 0;
  16. virtual BOOL UnLock() = 0;
  17. };
  18. //任务基类,所有要执行的任务都继承这个类
  19. class CJob
  20. {
  21. private:
  22. int      m_JobNo;//任务ID 用来调试是否绑定特定线程
  23. char*    m_JobName; //任务名字,用来调试是否绑定特定线程
  24. CThread* m_pWorkThread; //The thread associated with the job
  25. public:
  26. CJob();
  27. virtual ~CJob();
  28. CThread *GetWorkThread(void); //获取工作线程
  29. void SetWorkThread(CThread* pWorkThread);//设置工作线程
  30. virtual void Execute(void* ptr) = 0; //执行函数
  31. int      GetJobNo(void) const { return m_JobNo; }
  32. void     SetJobNo(int jobno){ m_JobNo = jobno;}
  33. char*    GetJobName(void) const { return m_JobName; }
  34. void     SetJobName(char* jobname);
  35. };
  36. void CJob::SetJobName(char* jobname)
  37. {
  38. if(NULL !=m_JobName)
  39. {
  40. free(m_JobName);
  41. m_JobName = NULL;
  42. }
  43. if(NULL !=jobname)
  44. {
  45. m_JobName = (char*)malloc(strlen(jobname)+1);
  46. strcpy(m_JobName,jobname);
  47. }
  48. }
  49. CThread* CJob::GetWorkThread(void)
  50. {
  51. return m_pWorkThread;
  52. }
  53. void CJob::SetWorkThread(CThread *pWorkThread)
  54. {
  55. m_pWorkThread = pWorkThread;
  56. }
  57. CJob::CJob(void) :m_pWorkThread(NULL),m_JobName(NULL), m_JobNo(0)
  58. {
  59. }
  60. CJob::~CJob()
  61. {
  62. if (NULL != m_JobName)
  63. {
  64. free(m_JobName);
  65. m_JobName = NULL;
  66. }
  67. }
  68. //线程状态
  69. typedef enum _ThreadState
  70. {
  71. THREAD_RUNNING = 0x0, //运行
  72. THREAD_IDLE = 0x1,//空闲
  73. THREAD_EXIT = 0X2,//退出
  74. }ThreadState;
  75. //线程基类
  76. class CThread
  77. {
  78. private:
  79. int m_ErrorCode; //错误码
  80. unsigned long m_ThreadID; //线程ID
  81. char* m_ThreadName; //线程名字
  82. ThreadState m_ThreadState; //线程状态
  83. HANDLE m_hthreadHandle; //线程句柄
  84. bool      m_IsExit;//是否退出
  85. protected:
  86. static unsigned __stdcall ThreadFunction(void*); //start调用此函数,此函数再调用run函数,执行实际的任务
  87. public:
  88. CThread();
  89. virtual ~CThread();
  90. virtual void Run() = 0;
  91. //设置线程状态
  92. void SetThreadState(ThreadState state);
  93. //获取线程状态
  94. ThreadState GetThreadState();
  95. //Start to execute the thread
  96. bool Start();
  97. //获取线程ID
  98. int GetThreadID(void);
  99. //设置错误码
  100. void SetErrorCode(int errorCode);
  101. //获取错误码
  102. int GetLastError(void);
  103. //设置线程名字
  104. void SetThreadName(char* threadName);
  105. //获取线程名字
  106. char* GetThreadName();
  107. //设置线程优先级
  108. bool     SetPriority(int priority);
  109. //获取线程优先级
  110. int      GetPriority(void);
  111. bool     Terminate(void);
  112. HANDLE GetThreadHandle();
  113. void SetThreadHandle(HANDLE hdl);
  114. void SetExitFlag(bool bExit);
  115. bool GetExitFlag();
  116. bool NeedExit();
  117. };
  118. bool CThread::NeedExit()
  119. {
  120. return m_IsExit;
  121. }
  122. void CThread::SetExitFlag(bool bExit)
  123. {
  124. m_IsExit = bExit;
  125. }
  126. bool CThread::GetExitFlag()
  127. {
  128. return m_IsExit;
  129. }
  130. bool CThread::Terminate(void)
  131. {
  132. _endthreadex(0);
  133. return TRUE;
  134. }
  135. HANDLE CThread::GetThreadHandle()
  136. {
  137. return m_hthreadHandle;
  138. }
  139. void CThread::SetThreadHandle(HANDLE hdl)
  140. {
  141. m_hthreadHandle = hdl;
  142. }
  143. void CThread::SetErrorCode(int errorCode)
  144. {
  145. m_ErrorCode = errorCode;
  146. }
  147. int CThread::GetLastError(void)
  148. {
  149. return m_ErrorCode;
  150. }
  151. CThread::CThread()
  152. {
  153. m_IsExit = FALSE;
  154. }
  155. CThread::~CThread()
  156. {
  157. }
  158. void CThread::SetThreadState(ThreadState state)
  159. {
  160. m_ThreadState = state;
  161. }
  162. ThreadState CThread::GetThreadState()
  163. {
  164. return m_ThreadState;
  165. }
  166. //Start to execute the thread
  167. bool CThread::Start()
  168. {
  169. unsigned threadID;
  170. HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunction, this, 0, &threadID);
  171. this->m_ThreadID = threadID;
  172. this->SetThreadHandle(hThread);
  173. return true;
  174. }
  175. unsigned __stdcall CThread::ThreadFunction(void* pArg)
  176. {
  177. CThread* pThread = (CThread*)pArg;
  178. pThread->Run();
  179. return TRUE;
  180. }
  181. int  CThread::GetThreadID(void)
  182. {
  183. return m_ThreadID;
  184. }
  185. void CThread::SetThreadName(char* threadName)
  186. {
  187. strncpy(m_ThreadName, threadName, strlen(threadName));
  188. }
  189. char* CThread::GetThreadName()
  190. {
  191. return m_ThreadName;
  192. }
  193. //线程互斥锁
  194. class CThreadMutex: public CLockObject
  195. {
  196. private:
  197. CRITICAL_SECTION m_CritSec;//临界区
  198. public:
  199. CThreadMutex();
  200. ~CThreadMutex();
  201. BOOL Lock();//加锁,阻塞式
  202. BOOL UnLock();//解锁
  203. BOOL TryLock();//加锁,非阻塞式
  204. };
  205. CThreadMutex::CThreadMutex()
  206. {
  207. #if (_WIN32_WINNT >= 0x0403)
  208. //使用 InitializeCriticalSectionAndSpinCount 可以提高性能
  209. ::InitializeCriticalSectionAndSpinCount(&m_CritSec,4000);
  210. #else
  211. ::InitializeCriticalSection(&m_CritSec);
  212. #endif
  213. }
  214. CThreadMutex::~CThreadMutex()
  215. {
  216. ::DeleteCriticalSection(&m_CritSec);
  217. }
  218. BOOL CThreadMutex::Lock()
  219. {
  220. ::EnterCriticalSection(&m_CritSec);
  221. return TRUE;
  222. }
  223. BOOL CThreadMutex::UnLock()
  224. {
  225. ::LeaveCriticalSection(&m_CritSec);
  226. return TRUE;
  227. }
  228. BOOL CThreadMutex::TryLock()
  229. {
  230. BOOL bRet = TryEnterCriticalSection(&m_CritSec);
  231. return bRet;
  232. }
  233. //条件变量
  234. class CThreadCondition
  235. {
  236. private:
  237. HANDLE m_phEvent; //句柄
  238. public:
  239. CThreadCondition();
  240. ~CThreadCondition();
  241. void Wait();
  242. void Signal();
  243. };
  244. CThreadCondition::CThreadCondition()
  245. {
  246. //第二个参数 bManualReset FALSE the system automatically resets the state to nonsignaled
  247. //If this parameter is TRUE, the function creates a manual-reset event object
  248. //第三个参数 bInitialState FALSE it is nonsignaled
  249. m_phEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
  250. }
  251. CThreadCondition::~CThreadCondition()
  252. {
  253. if (NULL != m_phEvent)
  254. {
  255. ::CloseHandle((m_phEvent));
  256. }
  257. }
  258. void CThreadCondition::Wait()
  259. {
  260. //If dwMilliseconds is INFINITE, the function will return only when the object is signaled.
  261. WaitForSingleObject(m_phEvent, INFINITE);
  262. ResetEvent(m_phEvent);
  263. }
  264. void CThreadCondition::Signal()
  265. {
  266. //Sets the specified event object to the signaled state
  267. SetEvent(m_phEvent);
  268. }
  269. //线程池类,主要负责调度线程,创建线程,删除线程
  270. class CThreadPool
  271. {
  272. friend class CWorkerThread;
  273. private:
  274. unsigned int m_nMaxNum; //当前线程池中所允许并发存在的线程的最大数目
  275. unsigned int m_nAvailLow; //当前线程池中所允许存在的空闲线程的最小数目
  276. //如果空闲数目低于该值,表明负载可能过重,此时有必要增加空闲线程池的数目
  277. //实现中我们总是将线程调整为m_InitNum个
  278. unsigned int m_nAvailHigh;//当前线程池中所允许的空闲的线程的最大数目,
  279. //如果空闲数目高于该值,表明当前负载可能较轻,此时将删除多余的空闲线程,删除后调整数也为m_InitNum个
  280. unsigned int m_nCurIdleThreadsNum;//当前线程池中实际存在的线程的个数,其值介于m_nAvailHigh和m_nAvailLow之间
  281. //如果线程的个数始终维持在m_nAvailLow和m_nAvailHigh之间,则线程既不需要创建,也不需要删除,保持平衡状态
  282. unsigned int m_nInitThreadsNum;//初始创建时线程池中的线程的个数
  283. protected:
  284. CWorkerThread* GetIdleThread(void);//获取空闲线程
  285. void    AppendToIdleList(CWorkerThread* jobthread);//线程加入空闲队列
  286. void    MoveToBusyList(CWorkerThread* idlethread);//线程加入忙碌队列
  287. void    MoveToIdleList(CWorkerThread* busythread);//线程加入空闲队列
  288. void    DeleteIdleThread(int num); //删除空闲线程
  289. void    CreateIdleThread(int num); //创建空闲线程
  290. public:
  291. CThreadMutex m_BusyMutex;//when visit busy list,use m_BusyMutex to Lock and unlock
  292. CThreadMutex m_IdleMutex;//when visit idle list,use m_IdleMutex to Lock and unlock
  293. CThreadMutex m_ThreadNumMutex;//变量锁, 目前用在m_nCurIdleThreadsNum修改上面
  294. CThreadCondition m_BusyCond; //m_BusyCond is used to sync busy thread list
  295. CThreadCondition m_IdleCond; //m_IdleCond is used to sync idle thread list
  296. CThreadCondition m_MaxNumCond;//m_MaxNumCond is used to sync m_nCurIdleThreadsNum
  297. vector<CWorkerThread*> m_vecAllThreads;//所有创建出来的线程集合
  298. vector<CWorkerThread*> m_vecBusyThreads;//忙碌线程队列,随着负载的多少会改变
  299. vector<CWorkerThread*> m_vecIdleThreads;//空闲线程队列,随着负的多少会改变
  300. public:
  301. void    SetMaxNum(int maxnum){m_nMaxNum = maxnum;} //设置线程池运行的最大线程数
  302. int     GetMaxNum(void){return m_nMaxNum;}
  303. void    SetAvailLowNum(int minnum){m_nAvailLow = minnum;} //设置最少空闲线程数
  304. int     GetAvailLowNum(void){return m_nAvailLow;}
  305. void    SetAvailHighNum(int highnum){m_nAvailHigh = highnum;} //设置最多空闲线程数
  306. int     GetAvailHighNum(void){return m_nAvailHigh;}
  307. int     GetCurIdleThreadsNum(void){return m_nCurIdleThreadsNum;} //获取当前空闲线程个数
  308. int     GetAllThreadsNum(void){return m_vecAllThreads.size();} //获取所有线程个数
  309. int     GetBusyThreadsNum(void){return m_vecBusyThreads.size();} //获取忙碌空闲线程个数
  310. void    SetInitNum(int initnum){m_nInitThreadsNum = initnum;}
  311. int     GetInitNum(void){return m_nInitThreadsNum;}
  312. CThreadPool();
  313. ~CThreadPool();
  314. CThreadPool(int initnum);
  315. void TerminateAll();
  316. void Run(CJob* job,void* jobdata);
  317. };
  318. //真正的工作线程,执行操作的线程
  319. class CWorkerThread : public CThread
  320. {
  321. private:
  322. CThreadPool* m_pThreadPool;//线程池
  323. CJob* m_pJob;//任务
  324. void* m_pJobData;//任务参数
  325. CThreadMutex m_VarMutex;//
  326. public:
  327. CThreadCondition   m_JobAddCond; //有新的任务时触发条件变量,每个线程一个条件变量,可以指定线程去执行任务
  328. CThreadMutex m_WorkMutex;//
  329. CWorkerThread();
  330. virtual ~CWorkerThread();
  331. void Run();
  332. void    AddNewJob(CJob* job,void* jobdata);
  333. CJob*   GetJob(void){return m_pJob;}
  334. void    SetThreadPool(CThreadPool* thrpool);
  335. CThreadPool* GetThreadPool(void){return m_pThreadPool;}
  336. void Terminate(void);
  337. };
  338. void CWorkerThread::Terminate(void)
  339. {
  340. //工作线程再处理任务结束才会解锁,这个时候再去退出线程,避免打断线程处理任务。
  341. m_WorkMutex.Lock();
  342. SetExitFlag(TRUE);
  343. //工作为假 代表要求线程退出
  344. m_pJob = NULL;
  345. m_pJobData = NULL;
  346. printf("thread [%d] ready to exit\n", GetThreadID());
  347. m_JobAddCond.Signal();
  348. m_WorkMutex.UnLock();
  349. WaitForSingleObject(GetThreadHandle(), INFINITE);
  350. CloseHandle(GetThreadHandle());
  351. }
  352. CWorkerThread::CWorkerThread()
  353. {
  354. m_pJobData = NULL;
  355. m_pJob = NULL;
  356. m_pThreadPool = NULL;
  357. }
  358. CWorkerThread::~CWorkerThread()
  359. {
  360. if (NULL != m_pJob) {delete m_pJob; m_pJob = NULL;}
  361. if (NULL != m_pThreadPool) {delete m_pThreadPool; m_pThreadPool = NULL;}
  362. }
  363. void CWorkerThread::Run()
  364. {
  365. printf("Enter CWorkerThread::Run\n");
  366. SetThreadState(THREAD_RUNNING);
  367. for(;;)
  368. {
  369. //当前线程不退出才需要等待任务的到来
  370. while ((NULL == m_pJob) && !NeedExit())
  371. {
  372. printf("thread [%d] wait for job \n", GetThreadID());
  373. m_JobAddCond.Wait();
  374. }
  375. if (NULL == m_pJob)
  376. {
  377. printf("thread [%d] exitFlag [%d]\n", GetThreadID(), NeedExit());
  378. if (NeedExit())
  379. {
  380. break;//不再等待任务,退出线程
  381. }
  382. else
  383. {
  384. //任务为NULL 但不是线程退出,跳过这个任务
  385. printf("m_pJob [%p] exitFlag [%d]\n", m_pJob, NeedExit());
  386. continue;
  387. }
  388. }
  389. m_WorkMutex.Lock();
  390. printf("thread [%d] accept the job [%d]\n", GetThreadID(), m_pJob->GetJobNo());
  391. //真正执行任务的地方
  392. m_pJob->Execute(m_pJobData);
  393. m_pJob->SetWorkThread(NULL);
  394. m_pJob = NULL;
  395. m_pJobData = NULL;
  396. m_pThreadPool->MoveToIdleList(this);
  397. SetThreadState(THREAD_IDLE);
  398. if(m_pThreadPool->m_vecIdleThreads.size() > m_pThreadPool->GetAvailHighNum())
  399. {
  400. m_pThreadPool->DeleteIdleThread(m_pThreadPool->m_vecIdleThreads.size() - m_pThreadPool->GetInitNum());
  401. }
  402. m_WorkMutex.UnLock();
  403. }
  404. printf("thread [%d] exit\n", GetThreadID());
  405. }
  406. void CWorkerThread::AddNewJob(CJob* pJob,void* jobdata)
  407. {
  408. assert(NULL != pJob);
  409. m_VarMutex.Lock();
  410. m_pJob = pJob;
  411. m_pJobData = jobdata;
  412. pJob->SetWorkThread(this);
  413. m_VarMutex.UnLock();
  414. printf("job [%d] add to the pool\n",m_pJob->GetJobNo());
  415. m_JobAddCond.Signal();
  416. }
  417. void CWorkerThread::SetThreadPool(CThreadPool* thrpool)
  418. {
  419. m_VarMutex.Lock();
  420. m_pThreadPool = thrpool;
  421. m_VarMutex.UnLock();
  422. }
  423. CThreadPool::CThreadPool()
  424. {
  425. m_nMaxNum = 50;
  426. m_nAvailLow = 5;
  427. m_nInitThreadsNum = 10;
  428. m_nCurIdleThreadsNum = 10;
  429. m_nAvailHigh = 20;
  430. m_vecBusyThreads.clear();
  431. m_vecIdleThreads.clear();
  432. int i;
  433. for (i=0; i<m_nInitThreadsNum; ++i)
  434. {
  435. CWorkerThread* pNewWorkThread = new CWorkerThread;
  436. pNewWorkThread->SetThreadPool(this);
  437. AppendToIdleList(pNewWorkThread);
  438. pNewWorkThread->Start();
  439. }
  440. }
  441. CThreadPool::CThreadPool(int initnum)
  442. {
  443. m_nMaxNum   = 30;
  444. m_nAvailLow = (initnum-10>0)?(initnum-10):3;
  445. m_nInitThreadsNum = m_nCurIdleThreadsNum = initnum ;
  446. m_nAvailHigh = initnum+10;
  447. m_vecAllThreads.clear();
  448. m_vecBusyThreads.clear();
  449. m_vecIdleThreads.clear();
  450. int i;
  451. for (i=0; i<m_nInitThreadsNum; ++i)
  452. {
  453. CWorkerThread* pNewWorkThread = new CWorkerThread;
  454. pNewWorkThread->SetThreadPool(this);
  455. AppendToIdleList(pNewWorkThread);
  456. pNewWorkThread->Start();
  457. }
  458. printf("CThreadPool::CThreadPool: Create Thread [%d] success\n", m_nInitThreadsNum);
  459. }
  460. CThreadPool::~CThreadPool()
  461. {
  462. TerminateAll();
  463. }
  464. void CThreadPool::TerminateAll()
  465. {
  466. int i;
  467. for (i=0; i<m_vecAllThreads.size(); ++i)
  468. {
  469. CWorkerThread* pWorkThread = m_vecAllThreads[i];
  470. pWorkThread->Terminate();
  471. }
  472. }
  473. //获取空闲的线程
  474. CWorkerThread* CThreadPool::GetIdleThread(void)
  475. {
  476. while (0 == m_vecIdleThreads.size())
  477. {
  478. printf("no idle threads, must wait\n");
  479. m_IdleCond.Wait();
  480. }
  481. m_IdleMutex.Lock();
  482. if (0 < m_vecIdleThreads.size())
  483. {
  484. CWorkerThread* pIdleThread = (CWorkerThread*)m_vecIdleThreads.front();
  485. printf("get idle thread %d \n", pIdleThread->GetThreadID());
  486. m_IdleMutex.UnLock();
  487. return pIdleThread;
  488. }
  489. m_IdleMutex.UnLock();
  490. printf("warning: no idle threads return\n");
  491. return NULL;
  492. }
  493. //add an idle thread to idle list
  494. void CThreadPool::AppendToIdleList(CWorkerThread* jobthread)
  495. {
  496. m_IdleMutex.Lock();
  497. m_vecIdleThreads.push_back(jobthread);
  498. m_vecAllThreads.push_back(jobthread);
  499. m_IdleMutex.UnLock();
  500. }
  501. //move and idle thread to busy thread
  502. void CThreadPool::MoveToBusyList(CWorkerThread* idlethread)
  503. {
  504. m_BusyMutex.Lock();
  505. m_vecBusyThreads.push_back(idlethread);
  506. m_nCurIdleThreadsNum--;
  507. m_BusyMutex.UnLock();
  508. m_IdleMutex.Lock();
  509. vector<CWorkerThread*>::iterator pos;
  510. pos = find(m_vecIdleThreads.begin(),m_vecIdleThreads.end(),idlethread);
  511. if(pos != m_vecIdleThreads.end())
  512. {
  513. m_vecIdleThreads.erase(pos);
  514. }
  515. m_IdleMutex.UnLock();
  516. }
  517. void CThreadPool::MoveToIdleList(CWorkerThread* busythread)
  518. {
  519. m_IdleMutex.Lock();
  520. m_vecIdleThreads.push_back(busythread);
  521. m_nCurIdleThreadsNum++;
  522. m_IdleMutex.UnLock();
  523. m_BusyMutex.Lock();
  524. vector<CWorkerThread*>::iterator pos;
  525. pos = find(m_vecBusyThreads.begin(),m_vecBusyThreads.end(),busythread);
  526. if(pos!=m_vecBusyThreads.end())
  527. m_vecBusyThreads.erase(pos);
  528. m_BusyMutex.UnLock();
  529. m_IdleCond.Signal();
  530. m_MaxNumCond.Signal();
  531. }
  532. //create num idle thread and put them to idlelist
  533. void CThreadPool::CreateIdleThread(int num)
  534. {
  535. int i;
  536. for (i=0;i<num;i++)
  537. {
  538. CWorkerThread* pWorkThread = new CWorkerThread();
  539. pWorkThread->SetThreadPool(this);
  540. AppendToIdleList(pWorkThread);
  541. m_ThreadNumMutex.Lock();
  542. m_nCurIdleThreadsNum++;
  543. m_ThreadNumMutex.UnLock();
  544. pWorkThread->Start();//begin the thread,the thread wait for job
  545. }
  546. }
  547. void CThreadPool::DeleteIdleThread(int num)
  548. {
  549. printf("Enter into CThreadPool::DeleteIdleThread\n");
  550. m_IdleMutex.Lock();
  551. printf("Delete Num is %dn",num);
  552. int i;
  553. for(i=0;i<num;i++)
  554. {
  555. CWorkerThread* thr;
  556. if(m_vecIdleThreads.size() > 0 )
  557. {
  558. thr = (CWorkerThread*)m_vecIdleThreads.front();
  559. printf("Get Idle thread %dn",thr->GetThreadID());
  560. }
  561. else
  562. {
  563. printf("no idle thread, no need to delete thread\n");
  564. break;
  565. }
  566. vector<CWorkerThread*>::iterator pos;
  567. pos = find(m_vecIdleThreads.begin(),m_vecIdleThreads.end(),thr);
  568. if(pos!=m_vecIdleThreads.end())
  569. m_vecIdleThreads.erase(pos);
  570. m_nCurIdleThreadsNum--;
  571. printf("The idle thread available num:%d n",m_nCurIdleThreadsNum);
  572. printf("The idlelist              num:%d n",m_vecIdleThreads.size());
  573. }
  574. m_IdleMutex.UnLock();
  575. }
  576. void CThreadPool::Run(CJob* job, void* jobdata)
  577. {
  578. assert(NULL != job);
  579. //if the busy thread num adds to m_nMaxNum,so we should wait
  580. if(m_nMaxNum <= GetBusyThreadsNum())
  581. {
  582. printf("busy threads beyond the max threads number in the pool, must wait for idle threads\n");
  583. m_MaxNumCond.Wait();
  584. }
  585. //负载过重,空闲线程少,需要创建新的线程, 使其数目达到m_InitNum
  586. if(m_vecIdleThreads.size() < m_nAvailLow)
  587. {
  588. if(GetAllThreadsNum()+m_nInitThreadsNum-m_vecIdleThreads.size() < m_nMaxNum )
  589. {
  590. //当前有m_vecIdleThreads.size()空闲线程, 另外再创建m_nInitThreadsNum - m_vecIdleThreads.size(), 当前总的空闲线程为m_nInitThreadsNum
  591. CreateIdleThread(m_nInitThreadsNum - m_vecIdleThreads.size());
  592. }
  593. else
  594. {
  595. CreateIdleThread(m_nMaxNum - GetAllThreadsNum());
  596. }
  597. }
  598. CWorkerThread*  pWorkthread = GetIdleThread();
  599. if(NULL != pWorkthread)
  600. {
  601. pWorkthread->m_WorkMutex.Lock();
  602. MoveToBusyList(pWorkthread);
  603. pWorkthread->SetThreadPool(this);
  604. job->SetWorkThread(pWorkthread);
  605. printf("Job [%d] bind to thread [%d] \n", job->GetJobNo(), pWorkthread->GetThreadID());
  606. pWorkthread->AddNewJob(job, jobdata);
  607. pWorkthread->m_WorkMutex.UnLock();
  608. }
  609. else
  610. {
  611. printf("impossible to going here\n");
  612. }
  613. }
  614. //线程管理类
  615. class CThreadManage
  616. {
  617. public:
  618. CThreadManage();
  619. CThreadManage(int num);
  620. virtual ~CThreadManage();
  621. void Run(CJob* pjob, void* pJobData);//运行任务
  622. void TerminateAll(); //停止所有的线程
  623. private:
  624. int m_nNumOfThread;  //初始时允许创建的最大的线程个数
  625. CThreadPool* m_pPool;//实际的线程池
  626. };
  627. CThreadManage::CThreadManage()
  628. {
  629. m_nNumOfThread = 10;
  630. m_pPool = new CThreadPool(m_nNumOfThread);
  631. }
  632. CThreadManage::CThreadManage(int num)
  633. {
  634. m_nNumOfThread = num;
  635. m_pPool = new CThreadPool(m_nNumOfThread);
  636. }
  637. CThreadManage::~CThreadManage()
  638. {
  639. if (NULL != m_pPool)
  640. {
  641. delete m_pPool;
  642. m_pPool = NULL;
  643. }
  644. }
  645. void CThreadManage::Run(CJob* pjob, void* pJobData)
  646. {
  647. m_pPool->Run(pjob, pJobData);
  648. }
  649. void CThreadManage::TerminateAll()
  650. {
  651. m_pPool->TerminateAll();
  652. }
  653. class myjob : public CJob
  654. {
  655. public:
  656. myjob(){}
  657. myjob(int i){SetJobNo(i);}
  658. ~myjob(){}
  659. void Execute(void* jobdata)    {
  660. printf("The Job comes from CXJOB\n");
  661. ::Sleep(2);
  662. }
  663. };
  664. #if 0
  665. int main()
  666. {
  667. CThreadManage* manage = new CThreadManage(50);
  668. for(int i=0;i<1000;i++)
  669. {
  670. myjob* job = new myjob(i);
  671. manage->Run(job, NULL);
  672. }
  673. ::Sleep(2);
  674. myjob* job = new myjob();
  675. manage->Run(job, NULL);
  676. manage->TerminateAll();
  677. return 0;
  678. }
  679. #endif

[C++][线程池][完整实现] 转:线程池原理及创建(C++实现)相关推荐

  1. 【Android 异步操作】线程池 ( 线程池使用示例 | 自定义线程池使用流程 | 自定义任务拒绝处理策略 | 完整代码示例 )

    文章目录 一.自定义线程池使用流程 二.自定义任务拒绝处理策略 三.完整代码示例 在博客 [Android 异步操作]线程池 ( 线程池简介 | 线程池初始化方法 | 线程池种类 | AsyncTas ...

  2. [线程池][完整实现] 转:线程池原理及创建(C++实现)

    在实际任务中经常会用到多线程,但是没用过线程池,我以前的方法比较暴力:1)创建线程,不断切换任务,保持线程一直运行,直到所有任务结束:2)不断的创建和销毁线程:一般都用1方法.最近和别人聊天,谈到线程 ...

  3. boost创建线程池_Java并发 之 线程池系列 (1) 让多线程不再坑爹的线程池

    目录 背景 线程池的来由 什么是线程池 背景总结 用法 通过Executors创建线程池 Executors及其服务的类 Executors常用的几个方法 一个线程池的例子 任务 池子 测试 说明 总 ...

  4. 线程池原理及创建(C++实现)

    本文给出了一个通用的线程池框架,该框架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关.另外该线程池具有动态伸缩性,它能根据执行任务的轻重自动调整线程池中线程的数量.文章的最后,我们 ...

  5. C++线程池原理及创建(转)

    C++线程池原理及创建(转) 来自http://www.cnblogs.com/cpper-kaixuan/p/3640485.html 本文给出了一个通用的线程池框架,该框架将与线程执行相关的任务进 ...

  6. java线程提交_从Java线程到线程池

    线程模型 线程模型分为两类,用户级线程(ULT)和内核级线程(KLT) 用户级线程(ULT):user level threads,系统内核对ULT无感知,线程的创建和调度都由用户级APP进程管理:即 ...

  7. 线程池原理及创建并C++实现

    本文给出了一个通用的线程池框架,该框架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关.另外该线程池具有动态伸缩性,它能根据执行任务的轻重自动调整线程池中线程的数量.文章的最后,我们 ...

  8. C++线程池原理及创建

    本文给出了一个通用的线程池框架,该框架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关.另外该线程池具有动态伸缩性,它能根据执行任务的轻重自动调整线程池中线程的数量.文章的最后,我们 ...

  9. 线程池原理及创建(转)

    本文给出了一个通用的线程池框架,该框架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关.另外该线程池具有动态伸缩性,它能根据执行任务的轻重自动调整线程池中线程的数量.文章的最后,我们 ...

最新文章

  1. CynosDB技术详解——存储集群管理
  2. 20154312曾林 - Exp1 PC平台逆向破解
  3. Oracle alter table详解
  4. 调用支付宝接口android最新,Android 外接sdk之支付宝
  5. python点的作用-python中三引号的作用(逗号的两点总结)
  6. sqlite命令行查看数据显示列头、java访问sqlite、java命令指定classpath
  7. 五十、简单的斗鱼分析案例
  8. pytorch已经安装成功了为什么不能使用import_使用auto keras的过程
  9. java复合赋值运算符_Java 之复合赋值运算符
  10. 清华大学 现代软件工程 学生特别想学的领域
  11. Matlab:批量文件命名
  12. Linux下磁盘阵列raid
  13. 深度学习课程笔记(十三)深度强化学习 --- 策略梯度方法(Policy Gradient Methods)...
  14. java web自动化测试_Python和Java语言,哪个更适合做自动化测试?
  15. python百度文库下载器_真正百度文库免费下载,比冰点文库下载器还更牛x!
  16. 【DevOps研发管理方案】一:方案简介
  17. 2018电大计算机操作题怎么评分,2018年度电大专科计算机应用基础学习知识win7系统上机操作技巧题操作技巧.doc...
  18. 第一课:两种方法教你如何注册小程序账号
  19. 查看linux负载的情况
  20. Leetcode——唯唯诺诺对并查集的初次相见

热门文章

  1. wsp可以编辑html吗,wps和office兼容吗
  2. android 行车记录仪分析,基于Android架构行车记录仪的异常掉电可播放视频方法与流程...
  3. 【Windows设置篇】字符集-简繁体的切换
  4. Ubuntu to go 制作(u盘驱动)
  5. H.264 软/硬编码器 画质量化分析评测
  6. 保护病毒库!主流杀毒软件备份全攻略
  7. [原创] 火焰文字的教程
  8. 共享网络电子商刊(iebook)营销盛宴
  9. MySql 查询各部门前3高工资
  10. 百望股份获评中国企业服务产业独角兽 赋能企业数字化变革!