线程池

来源:互联网 发布:刷脸解锁软件 编辑:程序博客网 时间:2024/06/08 03:12
// ThreadPool.cpp: implementation of the CThreadPool class.////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "ChatServer.h"#include "ThreadPool.h"#ifdef _DEBUG#undef THIS_FILEstatic 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;}

0 0
原创粉丝点击