线程池

线程池这个概念在很多地方都有,各种各样的版本。线程池的概念就是预先产生一些等待状态的线程,到有任务到来的时候,就通过某种方法激活空闲的线程去干活。线程忙完之后就又回到等待状态。ms也给我们提供了线程池的api。涉及到的api主要有这些。

  • CloseThreadpool
  • CloseThreadpoolCleanupGroup
  • CloseThreadpoolCleanupGroupMembers
  • CloseThreadpoolWait
  • CloseThreadpoolWork
  • CreateThreadpool
  • CreateThreadpoolCleanupGroup
  • CreateThreadpoolTimer
  • CreateThreadpoolWait
  • CreateThreadpoolWork
  • InitializeThreadpoolEnvironment
  • SetThreadpoolCallbackCleanupGroup
  • SetThreadpoolCallbackPool
  • SetThreadpoolThreadMaximum
  • SetThreadpoolThreadMinimum
  • SetThreadpoolTimer
  • SetThreadpoolWait
  • SubmitThreadpoolWork
  • WaitForThreadpoolWaitCallbacks   ms应该是使用workitem的这个东西实现的,具体没有研究过。感兴趣的可以看一下msdn。对于这个线程池这个东西c++的版本也有不少。我自己也实现了一份。在这里就贴主要的实现部分。具体的请查看我资源中ui-mgr-task(v2.0)及以上的源代码吧。

    #ifndef _BASE_THREAD_H_
    #define _BASE_THREAD_H_
    
    #pragma once
    
    class ITask;
    class CBaseThreadPool;
    
    class CBaseThread
    {
    public:
    	CBaseThread(CBaseThreadPool* pThreadPool);
    	virtual ~CBaseThread(void);
    public:
    	void Execute(ITask* Task); 
    	virtual long WaitForTask();
    	virtual long DoRealWork();
    	static ULONG WINAPI ThreadProc(void * Param);
    
    	CBaseThreadPool* GetThreadPool(){return m_pThreadPool;}
    	long Shutdown();
    
    	bool IsShutdown(){return m_bShutdown;}
    
    private:
    	CBaseThread(void);
    	CBaseThread(const CBaseThread& );
    	CBaseThread& operator=(const CBaseThread& );
    private:
    	CBaseThreadPool* m_pThreadPool;
    	ITask*			 m_pTask;
    	HANDLE			 m_hThread;
    	HANDLE			 m_hGotTaskEvent;
    	bool			 m_bShutdown;
    };
    
    
    
    
    
    
    #endif //_BASE_THREAD_H_


    #include <assert.h>
    #include "BaseThreadPool.h"
    #include "BaseThread.h"
    #include "ITask.h"
    
    CBaseThread::CBaseThread(CBaseThreadPool* pThreadPool)
    {
    	m_pThreadPool = pThreadPool;
    	m_pTask = NULL;
    	m_hGotTaskEvent = ::CreateEvent(NULL,FALSE,FALSE,NULL);
    	m_hThread = ::CreateThread(NULL,0,ThreadProc,this,CREATE_SUSPENDED,NULL);
    	::ResumeThread(m_hThread);
    	
    	m_bShutdown = false;
    }
    CBaseThread::~CBaseThread(void)
    {
    	m_bShutdown = true;
    // 	::WaitForSingleObject(m_hThread,10000);
    // 	::TerminateThread(m_hThread,1);
    	::CloseHandle(m_hThread);
    	::CloseHandle(m_hGotTaskEvent);
    }
    
    void CBaseThread::Execute(ITask* Task)
    {
    	m_pThreadPool->AddToRun(this);
    	m_pTask = Task;
    	SetEvent(m_hGotTaskEvent);
    }
    long CBaseThread::DoRealWork()
    {
    	m_pTask->AddToRun();
    	m_pTask->Work();
    	m_pTask->RemoveFromRun();
    	m_pTask->Release();
    	m_pTask = NULL;
    	m_pThreadPool->AddToIdle(this);
    	return S_OK;
    }
    long CBaseThread::WaitForTask()
    {
    	if(m_pTask)
    	{
    		ResetEvent(m_hGotTaskEvent);
    		return 1;
    	}
    	else
    	{	
    		for (int i = 0;!m_bShutdown && !m_pTask && i < 50; ++i)
    		{
    			if(::WaitForSingleObject(m_hGotTaskEvent,100) == WAIT_OBJECT_0)
    			{
    				return 1;
    			}
    		}		
    	}
    	return 0;
    }
    
    long CBaseThread::Shutdown()
    {
    	m_bShutdown = true;
    	if(m_pTask)
    	{
    		m_pTask->Abort();
    
    		::WaitForSingleObject(m_hThread,INFINITE);
    	}
    
    	return S_OK;
    }
    
    ULONG WINAPI CBaseThread::ThreadProc(void * Param)
    {
    	assert(Param);
    	CBaseThread* pThread = reinterpret_cast<CBaseThread*>(Param);
    
    _BEG:
    	//等待是否这个线程会被再次调度
    	while(!pThread->IsShutdown() && pThread->WaitForTask())
    	{
    		pThread->DoRealWork();
    	}
    	//注意后面成功之后不能再次应用这个Thread了
    	if(!pThread->IsShutdown() && !pThread->GetThreadPool()->DestoryThread(pThread))
    		goto _BEG;
    
    	return S_OK;
    }
    

    #ifndef _BASE_THREAD_POOL_H_
    #define _BASE_THREAD_POOL_H_
    
    #pragma once
    
    #include <list>
    #include <Windows.h>
    
    
    class CBaseThread;
    
    class CBaseThreadPool
    {
    public:
    	typedef std::list<CBaseThread*> THREAD_QUEUE;
    public:
    	CBaseThreadPool(void);
    	CBaseThreadPool(ULONG dwMaxThreadNum,ULONG dwMinThreadNum);
    	virtual ~CBaseThreadPool(void);
    public:
    	void Initialize();
    	void Uninitialize();
    	CBaseThread* GetIdleThread();
    	
    	virtual bool DestoryThread(CBaseThread* Thread);
    	
    	virtual CBaseThread* CreateThread();
    	
    	void AddToIdle(CBaseThread*);
    
    	void AddToRun(CBaseThread*);
    
    	void Shutdown();
    protected:
    	void _RemoveFromRun(CBaseThread* Thread);
    	void _RemoveFromIdle(CBaseThread* Thread);
    private:
    	THREAD_QUEUE			m_RunThreadQueue;
    	CRITICAL_SECTION		m_RunLock;
    
    	THREAD_QUEUE			m_IdleThreadQueue;
    	CRITICAL_SECTION		m_IdleLock;
    
    	HANDLE					m_hAddIdleEvent;
    
    	ULONG					m_dwMaxThreadNum;
    	ULONG					m_dwMinThreadNum;
    	bool					m_bShutdown;
    };
    
    
    
    #endif  //_BASE_THREAD_POOL_H_
    


    #include <algorithm>
    #include "Lock.h"
    #include "BaseThread.h"
    #include "BaseThreadPool.h"
    
    
    
    CBaseThreadPool::CBaseThreadPool(void)
    {
    	Initialize();
    }
    
    CBaseThreadPool::CBaseThreadPool(ULONG dwMaxThreadNum,ULONG dwMinThreadNum)
    {
    	Initialize();
    
    	m_dwMaxThreadNum = dwMaxThreadNum;
    	m_dwMinThreadNum = dwMinThreadNum;
    }
    
    CBaseThreadPool::~CBaseThreadPool(void)
    {
    	Uninitialize();
    }
    
    void CBaseThreadPool::Initialize()
    {
    	m_bShutdown = false;
    	m_dwMaxThreadNum = 2;
    	m_dwMinThreadNum = 1;
    	InitializeCriticalSection(&m_IdleLock);
    	InitializeCriticalSection(&m_RunLock);	
    
    	m_hAddIdleEvent = ::CreateEvent(NULL,TRUE,FALSE,NULL);
    }
    
    void CBaseThreadPool::Uninitialize()
    {
    	Shutdown();
    	DeleteCriticalSection(&m_IdleLock);
    	DeleteCriticalSection(&m_RunLock);
    
    	CloseHandle(m_hAddIdleEvent);
    }
    
    CBaseThread* CBaseThreadPool::GetIdleThread()
    {
    	CBaseThread* Thread = NULL;
    	if(m_bShutdown)
    		return NULL;
    	if(m_IdleThreadQueue.empty())
    	{
    		//判断当前正在运行的线程数,根据情况是否需要增加线程或者等待
    		//wait,注意这里的锁会不会造成长时间等待,或者死锁
    		if(m_IdleThreadQueue.size() + m_RunThreadQueue.size() < m_dwMaxThreadNum)
    		{
    			CBaseThread* pNewThread = CreateThread();
    			return pNewThread;
    		}
    		else
    		{
    			while(!m_bShutdown && ::WaitForSingleObject(m_hAddIdleEvent,100) == WAIT_TIMEOUT)
    			{
    				ResetEvent(m_hAddIdleEvent);
    				CAutoLock Lock2(&m_IdleLock);
    				if(!m_IdleThreadQueue.empty())
    				{
    					Thread = m_IdleThreadQueue.front();
    					m_IdleThreadQueue.pop_front();
    				}
    				
    			}
    		}
    	}
    	else
    	{
    		CAutoLock Lock(&m_IdleLock);
    		Thread = m_IdleThreadQueue.front();
    		m_IdleThreadQueue.pop_front();
    	}
    	
    	
    	return Thread;
    }
    
    bool CBaseThreadPool::DestoryThread(CBaseThread* Thread)
    {
    	if (m_bShutdown)
    	{
    		delete Thread;
    		Thread = NULL;
    		return true;
    	}
    	//判断当前idle中的数量
    	CAutoLockEx lock(&m_IdleLock);
    	lock.Lock();
    	if(m_IdleThreadQueue.size() > m_dwMinThreadNum)
    	{
    		_RemoveFromIdle(Thread);
    		lock.Unlock();
    
    		delete Thread;
    		Thread = NULL;
    		return true;
    	}
    	lock.Unlock();
    	
    	return false;
    }
    
    CBaseThread* CBaseThreadPool::CreateThread()
    {
    	return new CBaseThread(this);
    }
    
    void CBaseThreadPool::AddToIdle(CBaseThread* Thread)
    {
    	//从run中删除之后在添加
    	_RemoveFromRun(Thread);
    
    	CAutoLock Lock(&m_IdleLock);
    	m_IdleThreadQueue.push_back(Thread);
    
    	::SetEvent(m_hAddIdleEvent);
    }
    
    void CBaseThreadPool::AddToRun(CBaseThread* Thread)
    {
    	CAutoLock Lock(&m_RunLock);
    	m_RunThreadQueue.push_back(Thread);
    	
    }
    void CBaseThreadPool::_RemoveFromRun(CBaseThread* Thread)
    {
    	if(m_bShutdown)
    		return;
    	CAutoLock Lock(&m_RunLock);
    	THREAD_QUEUE::iterator it = find(m_RunThreadQueue.begin(),m_RunThreadQueue.end(),Thread);
    	if(it!=m_RunThreadQueue.end())
    	{
    		m_RunThreadQueue.erase(it);
    	}
    
    }
    void CBaseThreadPool::_RemoveFromIdle(CBaseThread* Thread)
    {
    	if(m_bShutdown)
    		return;
    	CAutoLock Lock(&m_IdleLock);
    	THREAD_QUEUE::iterator it = find(m_IdleThreadQueue.begin(),m_IdleThreadQueue.end(),Thread);
    	if(it!=m_IdleThreadQueue.end())
    	{
    		m_IdleThreadQueue.erase(it);
    	}
    }
    
    void CBaseThreadPool::Shutdown()
    {
    	m_bShutdown = true;
    	m_dwMinThreadNum = m_dwMaxThreadNum = 0;
    
    	CAutoLockEx lock(&m_RunLock);
    	lock.Lock();
    
    	THREAD_QUEUE::iterator it = m_RunThreadQueue.begin();
    	while(it!=m_RunThreadQueue.end())
    	{
    		(*it)->Shutdown();		//需要进一步检查,判断是否有可能出现死锁
    		++it;
    	}
    	m_RunThreadQueue.clear();
    	lock.Unlock();
    
    	CAutoLockEx lock2(&m_IdleLock);
    	lock2.Lock();
    
    	it = m_IdleThreadQueue.begin();
    	while (it!=m_IdleThreadQueue.end())
    	{
    		DestoryThread(*it);
    		++it;
    	}
    	m_IdleThreadQueue.clear();
    
    	lock2.Unlock();
    }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值