一個線程池的設計需要的幾個東西:
線程池管理器:負責線程池的創建,管理和維護,線程池的終止。
工作線程:實際就是線程接口和線程管理的
任務隊列:用於存儲需要執行的任務,實際是一個列表
線程接口:一個線程函數的實現(在此爲,還不知道還有沒有一個更好的實現)
任務接口:需要使用線程池的中的線程處理的任務都需要繼承於此接口。
一個簡單的邏輯就是:
工作線程,線程接口
任務接口和線程函數:
#ifndef __THREAD_H__
#define __THREAD_H__
#include <string>
#include <windows.h>
#include <process.h>
class Runnable
{
public:
virtual ~Runnable() {};
virtual void Run() = 0;
};
class CThread : public Runnable
{
private:
explicit CThread(const CThread & rhs);
public:
CThread();
CThread(Runnable * pRunnable);
CThread(const char * ThreadName, Runnable * pRunnable = NULL);
CThread(std::string ThreadName, Runnable * pRunnable = NULL);
~CThread(void);
/**
開始運行線程
@arg bSuspend 開始運行時是否掛起
**/
bool Start(bool bSuspend = false);
/**
運行的線程函數,可以使用派生類重寫此函數
**/
virtual void Run();
/**
當前執行此函數線程等待線程結束
@arg timeout 等待超時時間,如果爲負數,等待無限時長
**/
void Join(int timeout = -1);
/**
恢復掛起的線程
**/
void Resume();
/**
掛起線程
**/
void Suspend();
/**
終止線程的執行
**/
bool Terminate(unsigned long ExitCode);
unsigned int GetThreadID();
std::string GetThreadName();
void SetThreadName(std::string ThreadName);
void SetThreadName(const char * ThreadName);
private:
static unsigned int WINAPI StaticThreadFunc(void * arg);
private:
HANDLE m_handle;
Runnable * const m_pRunnable; //接口調用
unsigned int m_ThreadID;
std::string m_ThreadName;
volatile bool m_bRun;
};
#endif
實現:
#include "stdafx.h"
#include "Thread.h"
CThread::CThread(void) :
m_pRunnable(NULL),
m_bRun(false)
{
}
CThread::~CThread(void)
{
}
CThread::CThread(Runnable * pRunnable) :
m_ThreadName(""),
m_pRunnable(pRunnable),
m_bRun(false)
{
}
CThread::CThread(const char * ThreadName, Runnable * pRunnable) :
m_ThreadName(ThreadName),
m_pRunnable(pRunnable),
m_bRun(false)
{
}
CThread::CThread(std::string ThreadName, Runnable * pRunnable) :
m_ThreadName(ThreadName),
m_pRunnable(pRunnable),
m_bRun(false)
{
}
bool CThread::Start(bool bSuspend)
{
if(m_bRun)
{
return true;
}
if(bSuspend)
{
m_handle = (HANDLE)_beginthreadex(NULL, 0, StaticThreadFunc, this, CREATE_SUSPENDED, &m_ThreadID);
}
else
{
m_handle = (HANDLE)_beginthreadex(NULL, 0, StaticThreadFunc, this, 0, &m_ThreadID);
}
m_bRun = (NULL != m_handle);
return m_bRun;
}
void CThread::Run()
{
if(!m_bRun)
{
return;
}
if(NULL != m_pRunnable)
{
m_pRunnable->Run(); //接口對象運行函數
}
m_bRun = false;
}
void CThread::Join(int timeout)
{
if(NULL == m_handle || !m_bRun)
{
return;
}
if(timeout <= 0)
{
timeout = INFINITE;
}
::WaitForSingleObject(m_handle, timeout); //
}
void CThread::Resume()
{
if(NULL == m_handle || !m_bRun)
{
return;
}
::ResumeThread(m_handle); //
}
void CThread::Suspend()
{
if(NULL == m_handle || !m_bRun)
{
return;
}
::SuspendThread(m_handle); //
}
bool CThread::Terminate(unsigned long ExitCode)
{
if(NULL == m_handle || !m_bRun)
{
return true;
}
if(::TerminateThread(m_handle, ExitCode)) //
{
::CloseHandle(m_handle); //
return true;
}
return false;
}
unsigned int CThread::GetThreadID()
{
return m_ThreadID;
}
std::string CThread::GetThreadName()
{
return m_ThreadName;
}
void CThread::SetThreadName(std::string ThreadName)
{
m_ThreadName = ThreadName;
}
void CThread::SetThreadName(const char * ThreadName)
{
if(NULL == ThreadName)
{
m_ThreadName = "";
}
else
{
m_ThreadName = ThreadName;
}
}
unsigned int CThread::StaticThreadFunc(void * arg)
{
CThread * pThread = (CThread *)arg;
pThread->Run();
return 0;
}