// ThreadPool.cpp: implementation of the CThreadPool class.
//
//
#include "stdafx.h"
#include "ChatServer.h"
#include "ThreadPool.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//
// Construction/Destruction
//
CThreadPool::CThreadPool()
{
m_pHThread = NULL;
m_Semaphore = NULL;
m_hEvent = NULL;
}
CThreadPool::~CThreadPool()
{
if (m_pHThread != NULL)
{
for (int i = 0; i < m_nThreadCount; i++)
{
CloseHandle(m_pHThread[i]);
}
delete[] m_pHThread;
m_pHThread = NULL;
}
if (m_hEvent != NULL)
{
CloseHandle(m_hEvent);
m_hEvent = NULL;
}
if (m_Semaphore != NULL)
{
CloseHandle(m_Semaphore);
m_Semaphore = NULL;
}
}
unsigned int WINAPI CThreadPool::ThreadPoolProc(LPVOID lpParameter)
{
CThreadPool* pThreadPool = (CThreadPool*)lpParameter;
CWorkItem* pWorkItem = NULL;
BOOL bRet = FALSE;
DWORD dwWaitResult = WAIT_TIMEOUT;
//循环从任务队列中取出一项来执行
while (TRUE)
{
//等待destroy设置事件,让线程都主动超时退出
dwWaitResult = WaitForSingleObject(pThreadPool->m_hEvent,1000);
if (dwWaitResult == WAIT_TIMEOUT)
{
return 0;
}
dwWaitResult = WaitForSingleObject(
pThreadPool->m_Semaphore, // handle to semaphore
INFINITE);
//开始干活,否则就会被一直挂起
if (dwWaitResult == WAIT_OBJECT_0)
{
bRet = pThreadPool->GetWorkItem(pWorkItem);
if (!bRet)
{
continue;
}
ASSERT(pWorkItem != NULL);
if (pWorkItem == NULL)
{
continue;
}
//开始执行任务
pWorkItem->Excuse();
delete pWorkItem;
}
}
return 0;
}
//从事项队列中取出一项来处理
BOOL CThreadPool::GetWorkItem(CWorkItem*& pWorkItem)
{
BOOL bRet = FALSE;
bRet = m_cs.Lock();
if (m_pWorkItemQue.empty())
{
bRet = m_cs.Unlock();
return FALSE;
}
//从队列首取出代办事项
pWorkItem = m_pWorkItemQue.front();
//删除该代办事项
m_pWorkItemQue.pop();
bRet = m_cs.Unlock();
return TRUE;
}
//创建线程池,只调用一次
BOOL CThreadPool::Create(int nThreadCount)
{
if (nThreadCount <= 0)
{
return FALSE;
}
m_nThreadCount = nThreadCount;
m_Semaphore = CreateSemaphore(NULL,
0,//表示初始化的资源计数器,0表示都处于非触发态
9999999,//表示最大的资源计数器,这里指工作队列的最大长度应该
//小于此值,否则就无法处理
NULL);//不跨进程,所以不取名
if (m_Semaphore == NULL)
{
// Check for error.
return FALSE;
}
m_hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
if (m_hEvent == NULL)
{
return FALSE;
}
m_pHThread = new HANDLE[nThreadCount];
if (m_pHThread == NULL)
{
return FALSE;
}
for (int i = 0; i < nThreadCount; i++)
{
//创建线程池中的线程
m_pHThread[i] = (HANDLE)_beginthreadex(NULL,
NULL,
&ThreadPoolProc,
this,
0,
NULL);
if (m_pHThread[i] == NULL)
{
return FALSE;
}
}
return TRUE;
}
//销毁线程池
BOOL CThreadPool::Destroy()
{
CWorkItem* pWorkItem = NULL;
//这里需要设置一个事件,让所有线程自己主动退出
BOOL bRet = ResetEvent(m_hEvent);
if (!bRet)
{
return FALSE;
}
//释放一个资源计数器,也就是唤醒线程池中的线程可以开始干活了
if (!ReleaseSemaphore(
m_Semaphore, // handle to semaphore
m_nThreadCount, // increase count by one
NULL)) // not interested in previous count
{
// Deal with the error.
bRet = m_cs.Unlock();
return FALSE;
}
//等待所有线程全部退出,清理资源
WaitForMultipleObjects(m_nThreadCount,m_pHThread,TRUE,INFINITE);
if (m_Semaphore != NULL)
{
CloseHandle(m_Semaphore);
m_Semaphore = NULL;
}
if (m_hEvent != NULL)
{
CloseHandle(m_hEvent);
m_hEvent = NULL;
}
if (m_pHThread != NULL)
{
for (int i = 0; i < m_nThreadCount; i++)
{
CloseHandle(m_pHThread[i]);
}
delete[] m_pHThread;
m_pHThread = NULL;
}
while (!m_pWorkItemQue.empty())
{
pWorkItem = m_pWorkItemQue.front();
if (pWorkItem != NULL)
{
pWorkItem->Abort();
}
delete pWorkItem;
m_pWorkItemQue.pop();
}
return TRUE;
}
//将待完成工作事项添加到事项队列中去
BOOL CThreadPool::InsertWorkItem(CWorkItem* pWorkItem)
{
//因为工作事项是共有的,所以要同步,使用临界区同步
BOOL bRet = FALSE;
bRet = m_cs.Lock();
m_pWorkItemQue.push(pWorkItem);
//释放一个资源计数器,也就是唤醒线程池中的线程可以开始干活了
if (!ReleaseSemaphore(
m_Semaphore, // handle to semaphore
1, // increase count by one
NULL)) // not interested in previous count
{
// Deal with the error.
bRet = m_cs.Unlock();
return FALSE;
}
bRet = m_cs.Unlock();
return TRUE;
}
线程池
最新推荐文章于 2024-07-19 16:55:35 发布