线程池

// 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值