线程池

下面将从线程的设计思路及线程池的使用进行说明。

线程池管理主体设计思路是:

1、封装线程管理对象 MyThread,用于线程创建、线程开启、线程睡眠、任务绑定等操作。

2、封装空闲线程栈管理对象IdleThreadContainer,用于空闲线程栈的维护管理等操作。空闲的线程放于此栈中。

3、封装忙碌线程队列管理对象BusyThreadContainer,用于忙碌线程队列的维护及管理等操作。忙碌的线程放于此队列中。

4、封装任务管理对象MyTask,用于线程函数等任务信息的设置操作。

5、封装任务队列管理对象TaskContainer,用于任务队列的管理及维护等操作。

6、封装线程池管理对象CThreadPoolExp,用于线程池线程创建、线程任务添加、线程任务调度、忙碌线程及空闲线程队列维护管理等操作。开启一个管理线程,对线程任务调度进行管理。

#include <windows.h>

class  Task;
class CBaseThreadPool;

class MyThread
{
public:
    MyThread(CBaseThreadPool *pBaseThreadPool);
    virtual ~MyThread(void);
public:
    bool	StartMyThread();
    bool	CloseMyThread();
    bool	SuspendMyThread();
    bool	ResumeMyThread();
    bool	AssignTask(Task *pTask);
    bool	StartTask();
    static unsigned _stdcall ThreadProc(LPVOID lParam);
private:
    static void ReleaseMemory(MyThread *pThread);
public:
    DWORD			m_iThreadID;
    HANDLE			m_hThread;
    CBaseThreadPool *m_pBaseThreadPool;
private:
    bool			m_bIsExit;
    HANDLE			m_hEvent;
    Task			*m_pTask;
};
#include "mythread.h"
#include <process.h>
#include "task.h"
#include "ThreadPoolExp.h"


MyThread::MyThread(CBaseThreadPool *pBaseThreadPool)
    : m_iThreadID(0)
    , m_hThread(NULL)
    , m_pBaseThreadPool(pBaseThreadPool)
    , m_bIsExit(true)
    , m_hEvent(NULL)
    , m_pTask(NULL)
{
    m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
}


MyThread::~MyThread(void)
{
    CloseHandle(m_hEvent);
}

bool MyThread::StartTask()
{
    if ( NULL == m_pTask )
        return false;
    return ResumeMyThread();
}

unsigned _stdcall MyThread::ThreadProc(LPVOID lParam)
{
    MyThread *pThread = static_cast<MyThread *>(lParam);
    if ( NULL == pThread )
        return 1;
    DWORD ret = WAIT_FAILED;
    while (!pThread->m_bIsExit)
    {
        ret = WaitForSingleObject(pThread->m_hEvent, INFINITE);
        if ( WAIT_OBJECT_0 == ret )
        {
            if ( pThread->m_pTask )
            {
                pThread->m_pTask->TaskProc();
                //任务完成清除任务释放资源
                ReleaseMemory(pThread);
                //线程挂起,根据当前是否有新任务来判断是否将当前线程放入空闲线程栈
                pThread->m_pBaseThreadPool->SwitchActiveThread(pThread);
            }
        }
    }
    return 0;
}

void MyThread::ReleaseMemory(MyThread *pThread)
{
    if(!pThread)
    {
        return;
    }
    if(pThread->m_pTask)
    {
        delete(pThread->m_pTask);
        pThread->m_pTask = NULL;
    }
}

bool MyThread::StartMyThread()
{
    if ( !m_bIsExit )
        return true;
    m_hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, (LPVOID)this, 0, NULL);
    if ( NULL == m_hThread )
        return false;
    m_iThreadID = GetThreadId(m_hThread);
    m_bIsExit = false;
    return true;
}

bool MyThread::CloseMyThread()
{
    if ( NULL == m_hThread )
        return true;
    m_bIsExit = true;
    m_pTask = NULL;
    ResumeMyThread();
    WaitForSingleObject(m_hThread, INFINITE);
    CloseHandle(m_hThread);
    return true;
}

bool MyThread::SuspendMyThread()
{
    if ( NULL == m_hThread )
        return false;
    ResetEvent(m_hEvent);
    return true;
}

bool MyThread::ResumeMyThread()
{
    if ( NULL == m_hThread )
        return false;
    SetEvent(m_hEvent);
    return true;
}

bool MyThread::AssignTask(Task *pTask)
{
    if ( NULL == pTask )
        return false;
    m_pTask = pTask;
    return true;
}
#include <vector>
#include <stack>
#include "typedef.h"


class MyThread;

class IdleThreadContainer
{
public:
    IdleThreadContainer(void);
    virtual ~IdleThreadContainer(void);
public:
    MyThread*	Pop();
    bool		Push(MyThread *pThread);
    bool		IsEmpty();
    bool		Clear();
    int			GetSize();
private:
    std::stack<MyThread *> m_ThreadStack;
    CMyLock m_AutoLock;
};
#include "idlethreadcontainer.h"
#include "mythread.h"


IdleThreadContainer::IdleThreadContainer(void)
    : m_AutoLock(CMyLock())
{
}


IdleThreadContainer::~IdleThreadContainer(void)
{
}

MyThread* IdleThreadContainer::Pop()
{
    if ( IsEmpty() )
        return NULL;
    MyThread *pThread = NULL;
    CMyAutoLock autoLock(&m_AutoLock);
    if ( m_ThreadStack.empty() )
        return NULL;
    pThread = m_ThreadStack.top();
    pThread->ResumeMyThread();
    m_ThreadStack.pop();
    return pThread;
}

bool IdleThreadContainer::Push(MyThread *pThread)
{
    if ( NULL == pThread )
        return false;
    CMyAutoLock autoLock(&m_AutoLock);
    pThread->SuspendMyThread();
    m_ThreadStack.push(pThread);
    return true;
}

bool IdleThreadContainer::IsEmpty()
{
    CMyAutoLock autoLock(&m_AutoLock);
    bool ret = m_ThreadStack.empty();
    return ret;
}

bool IdleThreadContainer::Clear()
{
    if ( IsEmpty() )
        return true;
    CMyAutoLock autoLock(&m_AutoLock);
    MyThread *pThread = NULL;
    while (!m_ThreadStack.empty())
    {
        pThread = m_ThreadStack.top();
        pThread->CloseMyThread();
        delete pThread;
        m_ThreadStack.pop();
    }
    return true;
}

int IdleThreadContainer::GetSize()
{
    CMyAutoLock autoLock(&m_AutoLock);
    int iSize = m_ThreadStack.size();
    return iSize;
}
#include <list>
#include "typedef.h"

class MyThread;

class BusyThreadContainer
{
public:
    BusyThreadContainer(void);
    virtual ~BusyThreadContainer(void);
public:
    bool		AddThread(MyThread *pThread);
    bool		RemoveThread(MyThread *pThread);
    bool		IsEmpty();
    bool		Clear();
    int			GetSize();
private:
    std::list<MyThread *> m_ThreadList;
    CMyLock m_AutoLock;
};
#include "busythreadcontainer.h"
#include "mythread.h"


BusyThreadContainer::BusyThreadContainer(void)
    : m_AutoLock(CMyLock())
{
}


BusyThreadContainer::~BusyThreadContainer(void)
{
}

bool BusyThreadContainer::AddThread(MyThread *pThread)
{
    if ( NULL == pThread )
        return false;
    CMyAutoLock autoLock(&m_AutoLock);
    m_ThreadList.push_back(pThread);
    return true;
}

bool BusyThreadContainer::RemoveThread(MyThread *pThread)
{
    if ( NULL == pThread || IsEmpty() )
        return false;
    CMyAutoLock autoLock(&m_AutoLock);
    if ( IsEmpty() )
        return false;
    m_ThreadList.remove(pThread);
    return true;
}

bool BusyThreadContainer::IsEmpty()
{
    CMyAutoLock autoLock(&m_AutoLock);
    bool ret = m_ThreadList.empty();
    return ret;
}

bool BusyThreadContainer::Clear()
{
    if ( IsEmpty() )
        return true;
    CMyAutoLock autoLock(&m_AutoLock);
    std::list<MyThread *>::iterator it = m_ThreadList.begin();
    while ( it != m_ThreadList.end() )
    {
        (*it)->CloseMyThread();
        delete *it;
        ++it;
    }
    m_ThreadList.clear();
    return true;
}

int BusyThreadContainer::GetSize()
{
    CMyAutoLock autoLock(&m_AutoLock);
    int iSize = m_ThreadList.size();
    return iSize;
}

#include "typedef.h"

namespace
{
    enum PRIORITY
    {
        MIN = 1, NORMAL = 25, MAX = 50
    };
}

typedef bool (*pTaskFun)(LPVOID lParam);

class Task
{
public:
    Task():m_iTaskID(0) {}
    Task(int id):m_iTaskID(id) {}
    Task(int id, pTaskFun TaskFunAddress, LPVOID lParam)
        : m_iTaskID(id)
        , m_pTaskFun(TaskFunAddress)
        , m_lParam(lParam)
    {
    }
    virtual ~Task() {}
public:
    int GetID() { return m_iTaskID; }
    virtual bool SetTaskInfo(int id, pTaskFun TaskFunAddress, LPVOID lParam) = 0;
    virtual bool TaskProc() = 0;
    virtual bool TaskProc(pTaskFun TaskFunAddress, LPVOID lParam) = 0;
protected:
    int					m_iTaskID;
    pTaskFun			m_pTaskFun;
    LPVOID				m_lParam;
};

class MyTask
    : public Task
{
public:
    MyTask() {}
    MyTask(int id);
    MyTask(int id, pTaskFun TaskFunAddress, LPVOID lParam);
    virtual ~MyTask(void);
public:
    virtual bool SetTaskInfo(int id, pTaskFun TaskFunAddress, LPVOID lParam);
    virtual bool TaskProc();
    virtual bool TaskProc(pTaskFun TaskFunAddress, LPVOID lParam);
};
#include "task.h"

MyTask::MyTask(int id)
    : Task(id)
{
}

MyTask::MyTask(int id, pTaskFun TaskFunAddress, LPVOID lParam)
    : Task(id, TaskFunAddress, lParam)
{

}

MyTask::~MyTask(void)
{
}

bool MyTask::SetTaskInfo(int id, pTaskFun TaskFunAddress, LPVOID lParam)
{
    if ( NULL == TaskFunAddress || NULL == lParam )
        return false;
    m_iTaskID = id;
    m_pTaskFun = TaskFunAddress;
    m_lParam = lParam;
    return true;
}

bool MyTask::TaskProc()
{
    if ( NULL == m_pTaskFun || NULL == m_lParam )
        return false;
    return m_pTaskFun(m_lParam);
}

bool MyTask::TaskProc(pTaskFun TaskFunAddress, LPVOID lParam)
{
    if ( NULL == TaskFunAddress || NULL == lParam )
        return false;
    return TaskFunAddress(lParam);
}

#include <deque>
#include "typedef.h"

class Task;

class TaskContainer
{
public:
    TaskContainer(void);
    virtual ~TaskContainer(void);
public:
    Task*	Pop();
    bool	Push(Task *pTask);
    bool	PushFront(Task *pTask);
    bool	IsEmpty();
    bool	Clear();
    int		GetSize();
private:
    std::deque<Task *> m_TaskQueue;
    CMyLock m_AutoLock;
};

#include "taskcontainer.h"
#include "task.h"

TaskContainer::TaskContainer(void)
    : m_AutoLock(CMyLock())
{
}


TaskContainer::~TaskContainer(void)
{
}

Task* TaskContainer::Pop()
{
    if ( IsEmpty() )
        return NULL;
    Task *pTask = NULL;
    CMyAutoLock autoLock(&m_AutoLock);
    if ( m_TaskQueue.empty() )
        return NULL;
    pTask = m_TaskQueue.front();
    m_TaskQueue.pop_front();
    return pTask;
}

bool TaskContainer::Push(Task *pTask)
{
    if ( NULL == pTask )
        return false;
    CMyAutoLock autoLock(&m_AutoLock);
    m_TaskQueue.push_back(pTask);
    return true;
}

bool TaskContainer::PushFront(Task *pTask)
{
    if ( NULL == pTask )
        return false;
    CMyAutoLock autoLock(&m_AutoLock);
    m_TaskQueue.push_front(pTask);
    return true;
}

bool TaskContainer::IsEmpty()
{
    CMyAutoLock autoLock(&m_AutoLock);
    bool ret = m_TaskQueue.empty();
    return ret;
}

bool TaskContainer::Clear()
{
    CMyAutoLock autoLock(&m_AutoLock);
    m_TaskQueue.clear();
    return true;
}

int TaskContainer::GetSize()
{
    CMyAutoLock autoLock(&m_AutoLock);
    int iSize = m_TaskQueue.size();
    return iSize;
}

#include <Windows.h>
#include <process.h>
#include "typedef.h"
#include "taskcontainer.h"
#include "idlethreadcontainer.h"
#include "busythreadcontainer.h"


class Task;
class MyThread;

class CBaseThreadPool
{
public:
    CBaseThreadPool() {}
    virtual ~CBaseThreadPool() {}
public:
    virtual int			SetThreadNum(int iThreadNum) = 0;
    virtual bool		AddTask(Task *pTask, TASK_PRIORITY priority) = 0;
    virtual Task*		GetNewTask() = 0;
    virtual MyThread*	GetIdleThread() = 0;
    virtual bool		SwitchActiveThread(MyThread *pThread) = 0;
    virtual bool		StartThreadPool() = 0;
    virtual bool		DestroyThreadPool() = 0;
    virtual bool		IsExit() = 0;
};

class CThreadPoolExp
    : public CBaseThreadPool
{
public:
    CThreadPoolExp(void);
    virtual ~CThreadPoolExp(void);
public:
    virtual int			SetThreadNum(int iThreadNum);
    virtual bool		AddTask(Task *pTask, TASK_PRIORITY priority);
    virtual Task*		GetNewTask();
    virtual MyThread*	GetIdleThread();
    virtual bool		SwitchActiveThread(MyThread *pThread);
    virtual bool		StartThreadPool();
    virtual bool		DestroyThreadPool();
    virtual bool		IsExit();
public:
    static unsigned _stdcall ThreadProc(LPVOID lParam);
private:
    bool SuspendThread();
    bool ResumeThread();
    bool ManageThreads();
private:
    bool				m_bIsExit;
    bool                m_bIsResumed;       //线程是否被唤起
    int					m_iThreadNum;
    HANDLE				m_hThread;
    HANDLE				m_hSemaphore;       //调度线程唤起信号
    TaskContainer		m_TaskQueue;
    IdleThreadContainer	m_IdleThreadSTask;
    BusyThreadContainer	m_BusyThreadList;
};

#include "threadpoolexp.h"
#include "mythread.h"


CThreadPoolExp::CThreadPoolExp(void)
    : m_bIsExit(true)
    , m_bIsResumed(false)
    , m_iThreadNum(0)
    , m_hThread(NULL)
    , m_hSemaphore(NULL)
{
    m_hSemaphore = CreateEvent(NULL, TRUE, FALSE, NULL);
}


CThreadPoolExp::~CThreadPoolExp(void)
{
    DestroyThreadPool();
    CloseHandle(m_hSemaphore);
}

bool CThreadPoolExp::AddTask(Task *pTask, TASK_PRIORITY priority)
{
    if ( NULL == pTask )
        return false;
    if ( TASK_PRIORITY_HIGH == priority )
    {
        m_TaskQueue.PushFront(pTask);
    }
    else
    {
        m_TaskQueue.Push(pTask);
    }

    if ( !m_TaskQueue.IsEmpty() && !m_IdleThreadSTask.IsEmpty())
    {
        ResumeThread();     //唤起调度线程
    }
    return true;
}

bool CThreadPoolExp::SwitchActiveThread(MyThread *pThread)
{
    if ( m_TaskQueue.IsEmpty() )
    {
        m_BusyThreadList.RemoveThread(pThread);
        m_IdleThreadSTask.Push(pThread);
    }
    else
    {
        Task *pTask = NULL;
        pTask = m_TaskQueue.Pop();
        if ( NULL == pTask )
        {
            m_BusyThreadList.RemoveThread(pThread);
            m_IdleThreadSTask.Push(pThread);
            return true;
        }
//        OutputDebugString("pThread->AssignTask(pTask)\r\n");
        pThread->AssignTask(pTask);
        pThread->StartTask();
    }
    return true;
}

unsigned _stdcall CThreadPoolExp::ThreadProc(LPVOID lParam)
{
    CThreadPoolExp *pThreadPool = static_cast<CThreadPoolExp *>(lParam);
    pThreadPool->ManageThreads();
    return 0;
}

bool CThreadPoolExp::ManageThreads()
{
    DWORD ret = WAIT_FAILED;
    while ( true )
    {
        ret = WaitForSingleObject(m_hSemaphore, INFINITE);
        if(WAIT_OBJECT_0 == ret)
        {
            if ( m_bIsExit )
            {
                return false;
            }
            if ( m_TaskQueue.IsEmpty() )
            {
                SuspendThread();
            }
            else
            {
                MyThread *pThread = GetIdleThread();
                if ( NULL == pThread )
                {
                    SuspendThread();
                    continue;
                }
                Task *pTask = NULL;
                pTask = GetNewTask();
                if ( NULL == pTask )
                {
                    m_IdleThreadSTask.Push(pThread);
                    continue;
                }

                m_BusyThreadList.AddThread(pThread);
                pThread->AssignTask(pTask);
                pThread->StartTask();
            }
        }
    }
    return true;
}

bool CThreadPoolExp::SuspendThread()
{
    if(NULL == m_hThread)
    {
        return false;
    }
    if(!m_bIsResumed)   //已被睡眠则返回
    {
        return true;
    }
    bool  isSucceed = ResetEvent(m_hSemaphore);
    if(isSucceed)
    {
        m_bIsResumed = false;
    }
    return true;
}

bool CThreadPoolExp::ResumeThread()
{
    if(NULL == m_hThread)
    {
        return false;
    }
    if(m_bIsResumed)
    {
        return true;
    }
    bool  isSucceed = SetEvent(m_hSemaphore);
    if(isSucceed)
    {
        m_bIsResumed = true;
    }
    return true;
}

MyThread* CThreadPoolExp::GetIdleThread()
{
    if ( m_IdleThreadSTask.IsEmpty() )
        return NULL;
    return m_IdleThreadSTask.Pop();
}

Task* CThreadPoolExp::GetNewTask()
{
    if ( m_TaskQueue.IsEmpty() )
        return NULL;
    Task *pTask = NULL;
    pTask = m_TaskQueue.Pop();
    return pTask;
}

int CThreadPoolExp::SetThreadNum(int iThreadNum)
{
    m_iThreadNum = iThreadNum;
    return m_iThreadNum;
}

bool CThreadPoolExp::StartThreadPool()
{
    if ( 0 == m_iThreadNum || !IsExit() )
        return false;
    m_bIsExit = false;
    m_hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, this, 0, NULL);
    if ( NULL == m_hThread )
    {
        m_bIsExit = true;
        return false;
    }
    for ( int i = 0; i < m_iThreadNum; ++i )
    {
        MyThread *pThread = new MyThread(this);
        pThread->StartMyThread();
        m_IdleThreadSTask.Push(pThread);
    }

    return true;
}

bool CThreadPoolExp::DestroyThreadPool()
{
    if ( IsExit() )
        return true;
    m_bIsExit = true;
    Sleep(50);
    WaitForSingleObject(m_hThread, INFINITE);
    CloseHandle(m_hThread);
    ResetEvent(m_hSemaphore);

    m_TaskQueue.Clear();
    m_IdleThreadSTask.Clear();
    m_BusyThreadList.Clear();

    return true;
}

bool CThreadPoolExp::IsExit()
{
    return m_bIsExit;
}

#include <Windows.h>
#include <QString>

#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)

typedef  long long int64_Cam;
typedef  int int32_Cam;
typedef	 unsigned int uint32_Cam;
typedef  unsigned long long uint64_Cam;

typedef struct  ThreadInfo
{
    ThreadInfo(QString sql, QString path, LPVOID pObject)
        :m_sSql(sql)
        ,m_sFilePath(path)
        ,m_pObject(pObject)
    {

    }
    QString		m_sSql;			//数据导出数据库查询语句
    QString     m_sFilePath;	//导出文件存储路径
    LPVOID		m_pObject;		//窗口信息输出对象

}THREAD_INFO;

enum TASK_PRIORITY
{
    TASK_PRIORITY_NORMAL,
    TASK_PRIORITY_HIGH
};

class Task;

class CMyLock
{
public:
    CMyLock() {
        InitializeCriticalSectionAndSpinCount(&m_cs, 4000);
    }
    ~CMyLock() {
        DeleteCriticalSection(&m_cs);
    }
    void Lock() {
        EnterCriticalSection(&m_cs);
        //OutputDebugString("EnterCriticalSection(&m_cs);\r\n");
    }
    void UnLock() {
        LeaveCriticalSection(&m_cs);
        //OutputDebugString("LeaveCriticalSection(&m_cs);\r\n");
    }
private:
    CRITICAL_SECTION m_cs;
};

class CMyAutoLock
{
public:
    CMyAutoLock(CMyLock *pLock) : m_pLock(pLock) {
        if ( m_pLock )
            m_pLock->Lock();
    }
    ~CMyAutoLock() {
        if ( m_pLock )
            m_pLock->UnLock();
    }
private:
    CMyLock *m_pLock;
};
#endif // TYPEDEF_H

线程池的使用:

线程函数声明:

static bool funRun(LPVOID lParam); //需线程处理的任务

线程函数定义:
bool MyScene::funRun(LPVOID lParam)
{
    if(NULL == lParam)
    {
        return false;
    }
    THREAD_INFO *pInfo = static_cast<THREAD_INFO*>(lParam);
    if(pInfo)
    {
        qDebug()<<pInfo->m_sSql;
        qDebug()<<pInfo->m_sFilePath;
        MyScene *pMySence = static_cast<MyScene*>(pInfo->m_pObject);
        if(pMySence)
        {
            return;
        }
 
      emit pMySence->threadStarted();

 
        //do something
 
        delete(pInfo);//资源回收
        pInfo = NULL;
        emit pMySence->threadFinished();
    }
}
 

线程池的使用:

//线程池测试
    QString fixSql("");
    QString fixFilePath("");
    for(int i = 0; i < 10; ++i)
    {
        fixSql = tr("fixSql at:%1").arg(i);
        fixFilePath = tr("fixFilePath at:%1").arg(i);
 
        THREAD_INFO *pInfo = new THREAD_INFO(fixSql, fixFilePath, this);
        MyTask *pTask = new MyTask;
        pTask->SetTaskInfo(i, funRun, pInfo);
        ThreadPool::g_cThreadPoolExp->AddTask(pTask, TASK_PRIORITY_NORMAL);
    }







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值