c++地址池

ThreadPool.h

/*++
Copyright (C) 1996 - 2000.  Linkage Corporation.  All rights reserved.

Module Name
    
    ThreadPool.h
    
Abstract

    Declare class CThreadPool.
    
Created by

    HanZhiQian, Network Management Product Department, ID Card No.824        
    at 3/25/2004   11:05

Modified
    who                        when                why
    HanZhiQian                6/2/2004            to add more useful functions
    HanZhiQian                6/21/2004            to add function 'WaitForIdleState'

PLEASE KEEP THE COMMENT ABOVE. THANK YOU!
--*/


#ifndef _THREAD_POOL_H
#define _THREAD_POOL_H

#include <semaphore.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>
#include <list>

#ifndef ENTER_HP_UX
using namespace std;
#endif

typedef int        (*RequestRoutine)(void* arg);

class CThreadPool;

class CRequest {
public:
    CRequest(RequestRoutine cbrr, void *arg);
    CRequest();
    virtual ~CRequest();

protected:
    void*    m_arg;
    int        m_ret;
    RequestRoutine    m_cbrr;

    friend class CThreadPool;
};

typedef list<CRequest>    REQUEST_LIST;

class CThreadPool
{
public:
    CThreadPool(int size);
    virtual ~CThreadPool();

public:
    enum WORKER_STATUS {
        WS_IDLE,
        WS_BUSY
    };    // worker thread status

protected:
    int                m_nSize;    // worker thread count
    REQUEST_LIST    m_lstRequests;    // request queue
    pthread_t*        m_ptList;    // thread id list of work thread
    WORKER_STATUS*    m_wsList;    // status list of worker thread
    sem_t            m_sem;        // semaphore
    pthread_mutex_t    m_lock;    // request queue read-write lock

    bool            m_bStopping; // setting this flag true will
                        // prevent any new request from being pushed into the queue


private:
    static void* worker_proc(void* arg);    // worker thread callback routine

    // added at 6/2/2004, by hanzq
    void SetWorkerStatus(pthread_t tid, WORKER_STATUS ws);    // this routine sets a worker's status

                    
public:
    // added at 6/2/2004, by hanzq
    int  IsIdle();
    
    int QueueRequest(RequestRoutine cbrr, void* arg); // put a request in the back of the
                                                    // request queue
    int PriorRequest(RequestRoutine cbrr, void* arg); // put a request in the front of the 
                                                    // request queue

    int Start();    // this routine creates all worker threads by
                        // internal parameters and sets their initial status

    void Stop();    // this routine stops all worker threads at once, clears request queue
                    // and workers' status

    // added at 6/2/2004, by hanzq
    void SafeStop(); // this routine emits a terminating signal and waits until
                    // all requests are handled and all workers finish their current job.
    //返回线程等待队列大小                
    int getRequests_size();
    //返回线程正在处理的队列大小
    int    getWorkProc_size();

#ifdef HP
    // Solaris does not support the following characteristics
    // added at 6/2/2004, by hanzq
    void Suspend(); // this routine suspends all worker threads

    // added at 6/2/2004, by hanzq
    void Resume(); // this routine resumes all worker threads
#endif // HP

    // added at 6/21/2004, by hanzq
    void WaitForIdleState(); // to wait until all worker threads are idle
};

#endif // _THREAD_POOL_H

 

ThreadPool.cpp

/*++
Copyright (C) 1996 - 2000.  Linkage Corporation.  All rights reserved.

Module Name

    ThreadPool.h

Abstract

    Implements class CThreadPool.

Created by

    HanZhiQian, Network Management Product Department, ID Card No.824        
    at 3/25/2004   11:05

Modified
    who                        when                why

PLEASE KEEP THE COMMENT ABOVE. THANK YOU!
--*/

#include "ThreadPool.h"

#ifndef ENTER_HP_UX
#include <iostream>
using namespace std;
#endif

CRequest::CRequest(RequestRoutine cbrr, void *arg)
{
    m_cbrr = cbrr;

    m_arg = arg;

    m_ret = 0;

}

CRequest::CRequest()
{
    m_cbrr = NULL;
    m_arg = 0;
    m_ret = 0;
}

CRequest::~CRequest()
{

}

CThreadPool::CThreadPool(int size)
{
    m_nSize = size;

    m_ptList = new pthread_t[m_nSize];
    m_wsList = new WORKER_STATUS[m_nSize];
}

CThreadPool::~CThreadPool()
{
    Stop();

    if (m_ptList!=NULL) {
        delete[] m_ptList;
        m_ptList = NULL;
    }

    if (m_wsList!=NULL) {
        delete[] m_wsList;
        m_wsList = NULL;
    }

}

int CThreadPool::QueueRequest(RequestRoutine cbrr, void* arg)
{
    if (m_bStopping)
        return -1;

    pthread_mutex_lock(&m_lock);
    m_lstRequests.push_back(CRequest(cbrr, arg));
    pthread_mutex_unlock(&m_lock);

    sem_post(&m_sem);
    IsIdle();
    return 0;
}

int CThreadPool::PriorRequest(RequestRoutine cbrr, void* arg)
{
    if (m_bStopping)
        return -1;

    pthread_mutex_lock(&m_lock);
    m_lstRequests.push_front(CRequest(cbrr, arg));
    pthread_mutex_unlock(&m_lock);

    sem_post(&m_sem);

    return 0;
}

int CThreadPool::Start()
{
    sem_init(&m_sem, 0, 0);
    pthread_mutex_init(&m_lock, NULL);
    

    for (int i=0; i<m_nSize; i++)
        m_wsList[i] = WS_IDLE;
    pthread_attr_t thread_attr;
    size_t stack_size;
    int status;
    stack_size = 1024*1024*4;
    status = pthread_attr_init (&thread_attr);
    status = pthread_attr_setstacksize(&thread_attr, stack_size);
    for (int i=0; i<m_nSize; i++)
    {
        if (pthread_create(&m_ptList[i], &thread_attr, worker_proc, (void *)this)!=0)
            return -1;

    }

    m_bStopping = false;

    return 0;
}

void CThreadPool::Stop()
{
    if (m_ptList==NULL)
        return;

    for (int i=0;i<m_nSize;i++)
    {
        if (m_ptList[i]!=0) {
            pthread_cancel(m_ptList[i]);
            m_ptList[i] = 0;
        }
    }

    sem_destroy(&m_sem);
    pthread_mutex_destroy(&m_lock);

    //REQUEST_LIST::iterator rli;
    //for (rli=m_lstRequests.begin();rli!=m_lstRequests.end();rli++)
    //{
    //    CRequest *rq = (*rli);
    //    if (rq!=NULL)
    //        delete rq;
    //}

    m_lstRequests.clear();
}

void CThreadPool::SafeStop()
{
    m_bStopping = true;

    while (1) {
        if (IsIdle()==0 // all workers are idle
            && m_lstRequests.size()==0) // all requests are handled
            break;

        sleep(1);    // sleep for 1s
    }

    // call Stop()
    Stop();
}

void* CThreadPool::worker_proc(void* arg)
{
    CThreadPool *pThis = (CThreadPool *)arg;
    if (pThis==NULL)
        return 0;
    while (1) {
        sem_wait(&pThis->m_sem);

        pthread_mutex_lock(&pThis->m_lock);    // wait until the request queue 
                                    // can be read
        CRequest rq;

        if (pThis->m_lstRequests.size()>0) {
            rq = pThis->m_lstRequests.front();
            pThis->m_lstRequests.pop_front();
        }

        
        pthread_mutex_unlock(&pThis->m_lock);

        if (rq.m_cbrr!=NULL) {
            pThis->SetWorkerStatus(pthread_self(), CThreadPool::WS_BUSY);
            rq.m_ret = rq.m_cbrr(rq.m_arg);
            pThis->SetWorkerStatus(pthread_self(), CThreadPool::WS_IDLE);
        }

        // sleep for a instant
        struct timeval tvTime;
        tvTime.tv_sec = 0;
        tvTime.tv_usec = 10000;
        
        select(0,NULL,NULL,NULL,&tvTime);

    }

    return 0;
}


void CThreadPool::SetWorkerStatus(pthread_t tid, WORKER_STATUS ws)
{
    // find and set
    for (int i=0;i<m_nSize;i++) {
        if (m_ptList[i]==tid) {
            m_wsList[i] = ws;
            break;
        }
    }
}

int CThreadPool::IsIdle()
{
#ifdef _DEBUG
    int busy = 0, idle = 0;
    for (int i=0;i<m_nSize;i++)
        if (m_wsList[i]==WS_BUSY)
            busy ++;
        else
            idle ++;
#endif

    for (int imm=0;imm<m_nSize;imm++)
        if (m_wsList[imm]==WS_BUSY)
            return 1;

    return 0;
}

#ifdef HP
void CThreadPool::Resume()
{
    for (int i=0;i<m_nSize;i++)
        pthread_continue(m_ptList[i]);
}

void CThreadPool::Suspend()
{
    for (int i=0;i<m_nSize;i++)
        pthread_suspend(m_ptList[i]);
}
#endif // HP


void CThreadPool::WaitForIdleState()
{
    //const int TIMEOUT = 5*60;
    //for (int i=0;i<TIMEOUT;i++)
    while(1)
    {
        if (IsIdle()==0 // all workers are idle
            && m_lstRequests.size()==0) // all requests are handled 
        {
            break;
        }
                //cout<<"m_lstRequests.size()="<<m_lstRequests.size()<<endl;
        sleep(1);    // sleep for 1s
    }
}
/* BEGIN: Added by 69937, 2013/5/14   问题单号:打印线程等待的队列 */
int CThreadPool::getRequests_size()
{
    int size = m_lstRequests.size();
    return size;
}
/* END:   Added by 69937, 2013/5/14 */
/* BEGIN: Added by 69937, 2013/5/23   问题单号:打印线程正在处理的队列 */
int CThreadPool::getWorkProc_size()
{
    int busy = 0;
    for (int i=0;i<m_nSize;i++)
        if (m_wsList[i]==WS_BUSY)
            busy ++;
    return busy;
}
/* END:   Added by 69937, 2013/5/23 */

 

调用

CThreadPool    * ThreadPool = new CThreadPool(ThreadNum);
 ThreadPool->Start();

(gatherThread调用的函数名,DeviceList入参)

ThreadPool->QueueRequest((int (*)(void*))gatherThread, DeviceList);

 

 


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值