vc 简单完成端口线程池

原创
2014/12/12 08:54
阅读数 274
//临界值操作类
class CInterCriSec
{
public:
	CInterCriSec(DWORD dwSpinCount = DEFAULT_CRISEC_SPIN_COUNT)
		{VERIFY(::InitializeCriticalSectionAndSpinCount(&m_crisec, dwSpinCount));}
	~CInterCriSec()
		{::DeleteCriticalSection(&m_crisec);}

	void Lock()								{::EnterCriticalSection(&m_crisec);}
	void Unlock()							{::LeaveCriticalSection(&m_crisec);}
	BOOL TryLock()							{return ::TryEnterCriticalSection(&m_crisec);}
	DWORD SetSpinCount(DWORD dwSpinCount)	{return ::SetCriticalSectionSpinCount(&m_crisec, dwSpinCount);}

	CRITICAL_SECTION* GetObject()			{return &m_crisec;}

private:
	CInterCriSec(const CInterCriSec& cs);
	CInterCriSec operator = (const CInterCriSec& cs);

private:
	//临界值
	CRITICAL_SECTION m_crisec;
};
//任务接口
class IThreadPoolTaskWork
{
public:
	enum TaskStateEnum{ wait/*等待*/,begin/*开始*/,stop/*停止*/,over/*结束*/};
	friend class CThreadPool;
	IThreadPoolTaskWork()
	{
		m_TaskState=TaskStateEnum::wait;
		hThread=0;
        threadId=0;
		Number=-1;
	}
	int Number;
 protected:
   //任务的实现方式
   virtual void TaskWork()=0;  
   //线程句柄
   HANDLE hThread;
   // 线程ID
   UINT threadId;
   //任务状态
   TaskStateEnum m_TaskState;
};

   线程池:

class CThreadPool
{
protected:
	virtual IThreadPoolTaskWork* GetFirstTaskWork();
	CInterCriSec m_lock;
	UINT m_MinThreadCount;
	UINT m_MaxThreadCount;
public:
		   struct ThreadData{
			  //线程句柄
		      HANDLE hThread;
			  // 线程ID
			  UINT threadId;
			  HANDLE  CompletePort;
			  IThreadPoolTaskWork* pTaskWork;
			  bool TaskFinish;/**显示是否完成任务**/
			  ThreadData(): hThread(NULL), threadId(0),CompletePort(0),TaskFinish(true),pTaskWork(NULL)
			  {
				  
			  }
		   };
		   int nThreadCount;
		   HANDLE MrgCompletePort;
		   std::vector<ThreadData*> m_threads;
		   std::vector<IThreadPoolTaskWork *> m_Tasks;
		   ThreadData* GetCurrentThread();
		   

		   CThreadPool(void);
		   ~CThreadPool(void); 
		   //线程池停止事件
		   HANDLE m_hStopEvent;
		   //启动线程池
		   void BeginPool(UINT Min=3,UINT Max=3);
		   //结束线程池
		   void EndPool(DWORD timeout = INFINITE);
		   // 线程回调
		   void CallWorkThreadProc(HANDLE  CompletePort);
		   //添加任务
		   virtual void AddTaskWork(IThreadPoolTaskWork *work);
		   //得到委完成的任务数量
		   int GetUnFinishTaskWork();
		   //激活任务
		   void ActiveWorkThread();

};

CThreadPool::CThreadPool(void)
{
	nThreadCount=0;
}


CThreadPool::~CThreadPool(void)
{
}

// 工作者线程回调
static unsigned __stdcall WorkerProc(LPVOID lpParameter)
{
	
	CThreadPool* pThreadPool = (CThreadPool*) lpParameter;
	CThreadPool::ThreadData *pThread=pThreadPool->GetCurrentThread();
	printf("进入线程%x \n",pThread->hThread);
	while (TRUE)
    {
		DWORD BytesTransferred,KEY;
		OVERLAPPED	PerIOData;
		printf("等待线程:%x \n",pThread->hThread);
		pThreadPool->CallWorkThreadProc(pThread->CompletePort);
		if (GetQueuedCompletionStatus(pThread->CompletePort,&BytesTransferred,(LPDWORD)&KEY, (LPOVERLAPPED*)&PerIOData,INFINITE))
		{  
			//printf("任务完成,状态码:%d \n",GetLastError());
		}
		//处理线程任务
		
    }
	printf("退出%d \n",pThread->threadId);
	return 0;
}
//线程调度员
static unsigned __stdcall MrgThreadProc(LPVOID lpParameter)
{
	CThreadPool* pThreadPool = (CThreadPool*) lpParameter;
	while(1)
	{
	    DWORD BytesTransferred,KEY;
		OVERLAPPED	PerIOData;
		Sleep(100);
	    pThreadPool->ActiveWorkThread();
	}
}
//激活任务
 void CThreadPool::ActiveWorkThread()
 {
	int count=GetUnFinishTaskWork();
	
	if(count>0)
	{
		printf("任务数%d \n",count);
		for(int i=0;i<this->m_threads.size();i++)
		{
			if(m_threads[i]->TaskFinish)
			{
               
				IThreadPoolTaskWork *work=GetFirstTaskWork();
				if(work==NULL) 
					return;
				this->m_lock.Lock();
				m_threads[i]->TaskFinish=false;
				work->m_TaskState=IThreadPoolTaskWork::begin;
				work->hThread=m_threads[i]->hThread;
				work->threadId=m_threads[i]->threadId;
				m_threads[i]->pTaskWork=work;//给线程分配任务
				this->m_lock.Unlock();

				DWORD BytesTransferred=0,KEY=0;
				OVERLAPPED				PerIOData;
				memset(&PerIOData,0,sizeof(OVERLAPPED));
				if(!PostQueuedCompletionStatus(
				m_threads[i]->CompletePort,
				BytesTransferred,
				KEY,
				&PerIOData))
				{
				   ASSERT(0);
				}
				count=GetUnFinishTaskWork();
				printf("剩余任务数%x \n",count);
				printf("激活线程%x,绑定任务号:%d \n",m_threads[i]->hThread,m_threads[i]->pTaskWork->Number );
				
			}
		}
	}
 }
void CThreadPool::BeginPool(UINT Min,UINT Max)
{
	if(Min<=0)
		Min=1;
	nThreadCount=Min;
	if(Max<Min)
		Max=Min;
	this->m_MinThreadCount=Min;
	this->m_MaxThreadCount=Max;
	if(nThreadCount==0)
	{
		  //SYSTEM_INFO systemInfo;
		  //GetSystemInfo(&systemInfo);
		  //nThreadCount = systemInfo.dwNumberOfProcessors;
		  //if(nThreadCount<3)
			 // nThreadCount=3;
		  m_hStopEvent=CreateEvent(NULL,TRUE,TRUE,NULL);
		  for(int i=0;i<nThreadCount;i++)
		  {
			  ThreadData* pThread = new ThreadData;
			  pThread->CompletePort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,NULL,0);
			  pThread->hThread=(HANDLE)_beginthreadex(NULL, NULL, WorkerProc, (LPVOID)this, 0, &pThread->threadId);
			  m_threads.push_back(pThread);
		  }

		 MrgCompletePort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,NULL,0);
		 _beginthreadex(NULL, NULL, MrgThreadProc, (LPVOID)this, 0, NULL);
	}
}

void CThreadPool::EndPool(DWORD timeout)
{
	        std::vector<HANDLE> threadHandles;
			for (int i = 0, count = m_threads.size(); i < count; i++)
			{
				ThreadData* thread = m_threads[i];
				if (thread->hThread != NULL)
				{
					threadHandles.push_back(thread->hThread);
				}
			}

			if (!threadHandles.empty())
			{
				if (m_hStopEvent != NULL)
				{
					SetEvent(m_hStopEvent);
				}
				//INFINITE 永远等待
				if (WAIT_OBJECT_0 != WaitForMultipleObjects(threadHandles.size(), &threadHandles[0], TRUE, timeout))
				{
					ASSERT(false);
				}

				for (int i = 0, count = threadHandles.size(); i < count; i++)
				{
					CloseHandle(threadHandles[i]);
				}
			}

			if (m_hStopEvent != NULL)
			{
				CloseHandle(m_hStopEvent);
				m_hStopEvent = NULL;
			}

			for (int i = 0, count = m_threads.size(); i < count; i++)
			{
				delete m_threads[i];
			}
			m_threads.clear();
}

//
void CThreadPool::CallWorkThreadProc(HANDLE  CompletePort){

	
	ThreadData *pThread=GetCurrentThread();
	if(pThread==NULL)
		return;
	if(pThread->pTaskWork!=NULL)
	{
		pThread->pTaskWork->TaskWork();
		printf("执行完成 线程%x,任务号%d \n",pThread->hThread,pThread->pTaskWork->Number );
		CInterCriSec lock;
		lock.Lock();
		pThread->pTaskWork->m_TaskState=IThreadPoolTaskWork::over;
		pThread->pTaskWork=NULL;
		pThread->TaskFinish=true;//标记该线程空闲
		lock.Unlock();
	}
	/**/
}

//添加任务
void CThreadPool::AddTaskWork(IThreadPoolTaskWork *work)
{
	work->Number=m_Tasks.size();
	m_Tasks.push_back(work);
}
//获取当前线程信息
CThreadPool::ThreadData* CThreadPool::GetCurrentThread()
{
	CInterCriSec lock;
	lock.Lock();
	DWORD threadId = ::GetCurrentThreadId();
	for (int i = 0;i<m_threads.size(); i++)
	{
		if (m_threads[i]->threadId == threadId)
		{
			return m_threads[i];
		}
	}
	lock.Unlock();
	ASSERT(false);
	return NULL;
}

//得到第一个未分配的任务
IThreadPoolTaskWork* CThreadPool::GetFirstTaskWork()
{
	IThreadPoolTaskWork *work=NULL;
		for(int i=0;i<this->m_Tasks.size();i++)
		{
		    work=this->m_Tasks[i];
			if(work->hThread==NULL&&work->threadId==NULL)
			{
			   return work;
			}
		}
	
	return NULL;
}

//得到未分配的任务的数量
int CThreadPool::GetUnFinishTaskWork()
{
	int count=0;
	IThreadPoolTaskWork *work=NULL;
	for(int i=0;i<this->m_Tasks.size();i++)
	{
		work=this->m_Tasks[i];
		if(work->hThread==NULL&&work->threadId==NULL)
		{
			count++;
		}
	}
	
	return count;
}


展开阅读全文
打赏
1
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
1
分享
返回顶部
顶部