C++线程池如何实现?有什么好处?谁有源码?

tech_study_00 2010-01-18 04:45:59
C++线程池的优点在哪里?

谁有相关代码?
...全文
1320 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
lijianli9 2012-05-22
  • 打赏
  • 举报
回复
建议lz看下windows核心编程 讲解线程的几个章节,以及win32多线程程序设计,先回用线程,然后再深入研究,
wocow3 2012-05-17
  • 打赏
  • 举报
回复
优点:方便异步调用、定时器队列,控制线程数量
dfasri 2012-05-17
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

引用 8 楼 的回复:
线程池和多线程没有必然联系。


顶!

多线程的困难在于时序的不确定,也就是处理同步问题,而线程池,我是觉得这东西跟内存池没什么区别。
[/Quote]

唉, 线程池就所用到的, 就是非常简单的时序, 连这时序都不会弄, 写多线程的程序能写出安全的代码么? 编程还是要打好扎实的基础.
zhanshen2891 2012-05-17
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
线程池和多线程没有必然联系。
[/Quote]

顶!

多线程的困难在于时序的不确定,也就是处理同步问题,而线程池,我是觉得这东西跟内存池没什么区别。
dfasri 2012-05-16
  • 打赏
  • 举报
回复
线程池都不会写, 别写多线程程序, 写了也白写, 肯定错误的
lijianli9 2012-05-16
  • 打赏
  • 举报
回复
线程池和多线程没有必然联系。
lijianli9 2012-05-15
  • 打赏
  • 举报
回复
ls的代码存在bug,我在项目中用过。
ls443085074 2012-05-14
  • 打赏
  • 举报
回复


#if !defined(AFX_THREADPOOL_H__653A92C6_53BE_42B9_90BD_26F5DC231A56__INCLUDED_)
#define AFX_THREADPOOL_H__653A92C6_53BE_42B9_90BD_26F5DC231A56__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#pragma warning( disable: 4786 )
#include <queue>
using namespace std ;
#pragma warning( default: 4786 )


/*e.g. bool MyThreadPoolCallback(LPVOID pMyData)*/
typedef bool (*THREAD_POOL_EXECUTE_FN)(LPVOID);

typedef struct _tagTHREAD_POOL_TASK /*线程池所使用的工作函数格式*/
{

THREAD_POOL_EXECUTE_FN pFunction; /*执行函数(工作函数)*/
LPVOID pExtraInfo; /*附加消息*/
}
THREAD_POOL_TASK, *PTHREAD_POOL_TASK;
//////////////////////////////////////////////////////////////////////
/*线程池所使用的数据结构*/

#define THREADPOOL_MAX_THREAD_COUNT 24 /*设置默认活动线程个数*/
#define THREADPOOL_MAX_TASK_COUNT 1024 /*设置最大可开线程个数*/

typedef struct _tagTHREAD_POOL_QUEUE_INFO /*线程池中工作函数队列信息*/
{
THREAD_POOL_TASK FuncInfo; /*工作函数*/
UINT ixTask; /*工作函数索引*/
} THREAD_POOL_QUEUE_INFO, * PTHREAD_POOL_QUEUE_INFO;

typedef unsigned int (__stdcall* THREAD_PROC)(void *);

typedef struct _tagTHREAD_DATA /*线程信息*/
{
unsigned long hThread; /*线程句柄*/
unsigned int nThreadId; /*线程ID*/
unsigned int nFlags; /*线程状态标示,例如标示是否杀死线程*/
}
THREAD_DATA, *PTHREAD_DATA;
typedef struct _tagTHREADPOOL_STATE
{
UINT m_cntMaxThread; /*最大线程个数*/
UINT m_cntMaxTasks; /*最大工作数*/
UINT m_cntThreads; /*活动线程个数*/
UINT m_backlogTasks; /*工作积压程度*/
}
THREADPOOL_STATE,PTHREADPOOL_STATE;

class CThreadPool
{
queue<PTHREAD_POOL_QUEUE_INFO> m_TaskQueue; /*工作函数队列*/
int *m_aFreeIndex; /*工作函数索引号*/
THREAD_DATA *m_aThreadData; /*线程信息结构体*/
UINT m_cntThreads; /*活动线程个数*/
PTHREAD_POOL_QUEUE_INFO m_aTasks; /*工作函数队列*/
HANDLE m_hTaskQueueSync; /*工作函数队列信号量*/
HANDLE m_hClientSync; /*线程池信号量*/

public:
static unsigned int __stdcall WorkerThreadProc( void * pInfo);

public:
UINT GetLeisureThreadCount();

UINT GetMaxThreadCount();
UINT GetUnsettledTaskCount();
CThreadPool();
virtual ~CThreadPool();
bool Initialize( UINT cntThreads=1/*Default value*/,
UINT nMaxThreadCount= THREADPOOL_MAX_THREAD_COUNT,
UINT nMaxTaskCount= THREADPOOL_MAX_TASK_COUNT );/*线程池初始化函数*/
void Uninitialize();/*线程池销毁函数*/
bool AssignTask(PTHREAD_POOL_TASK pTask);/*添加任务函数*/
void WorkerThreadProc();/*线程回调函数*/

private:
UINT m_cntRemove;
UINT m_cntMaxThread; /*最大线程个数*/
UINT m_cntMaxTasks; /*最大工作函数个数*/

private:
UINT m_iLeisureThreadCount;
UINT m_iUnsettledTaskCount;
void NotifyAll(UINT nMsg, WPARAM wParam, LPARAM lParam);/*截获系统消息,销毁线程池*/
void FreeThreadDataBlock(UINT ixThread);/*杀死线程*/
UINT GetMyThreadDataIndex();/*获取线程索引*/
void RemoveIfMarked();/*杀死被标记的线程*/
void MarkThreadsForDelete(UINT cntThrds);/*标记将要被杀死的线程*/
void AllocNewThreads(UINT cntThrds,unsigned int nFlag);/*分配一个新线程*/
};

#endif // !defined(AFX_THREADPOOL_H__653A92C6_53BE_42B9_90BD_26F5DC231A56__INCLUDED_)
ls443085074 2012-05-14
  • 打赏
  • 举报
回复


#if !defined(AFX_THREADPOOL_H__653A92C6_53BE_42B9_90BD_26F5DC231A56__INCLUDED_)
#define AFX_THREADPOOL_H__653A92C6_53BE_42B9_90BD_26F5DC231A56__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#pragma warning( disable: 4786 )
#include <queue>
using namespace std ;
#pragma warning( default: 4786 )


/*e.g. bool MyThreadPoolCallback(LPVOID pMyData)*/
typedef bool (*THREAD_POOL_EXECUTE_FN)(LPVOID);

typedef struct _tagTHREAD_POOL_TASK /*线程池所使用的工作函数格式*/
{

THREAD_POOL_EXECUTE_FN pFunction; /*执行函数(工作函数)*/
LPVOID pExtraInfo; /*附加消息*/
}
THREAD_POOL_TASK, *PTHREAD_POOL_TASK;
//////////////////////////////////////////////////////////////////////
/*线程池所使用的数据结构*/

#define THREADPOOL_MAX_THREAD_COUNT 24 /*设置默认活动线程个数*/
#define THREADPOOL_MAX_TASK_COUNT 1024 /*设置最大可开线程个数*/

typedef struct _tagTHREAD_POOL_QUEUE_INFO /*线程池中工作函数队列信息*/
{
THREAD_POOL_TASK FuncInfo; /*工作函数*/
UINT ixTask; /*工作函数索引*/
} THREAD_POOL_QUEUE_INFO, * PTHREAD_POOL_QUEUE_INFO;

typedef unsigned int (__stdcall* THREAD_PROC)(void *);

typedef struct _tagTHREAD_DATA /*线程信息*/
{
unsigned long hThread; /*线程句柄*/
unsigned int nThreadId; /*线程ID*/
unsigned int nFlags; /*线程状态标示,例如标示是否杀死线程*/
}
THREAD_DATA, *PTHREAD_DATA;
typedef struct _tagTHREADPOOL_STATE
{
UINT m_cntMaxThread; /*最大线程个数*/
UINT m_cntMaxTasks; /*最大工作数*/
UINT m_cntThreads; /*活动线程个数*/
UINT m_backlogTasks; /*工作积压程度*/
}
THREADPOOL_STATE,PTHREADPOOL_STATE;

class CThreadPool
{
queue<PTHREAD_POOL_QUEUE_INFO> m_TaskQueue; /*工作函数队列*/
int *m_aFreeIndex; /*工作函数索引号*/
THREAD_DATA *m_aThreadData; /*线程信息结构体*/
UINT m_cntThreads; /*活动线程个数*/
PTHREAD_POOL_QUEUE_INFO m_aTasks; /*工作函数队列*/
HANDLE m_hTaskQueueSync; /*工作函数队列信号量*/
HANDLE m_hClientSync; /*线程池信号量*/

public:
static unsigned int __stdcall WorkerThreadProc( void * pInfo);

public:
UINT GetLeisureThreadCount();

UINT GetMaxThreadCount();
UINT GetUnsettledTaskCount();
CThreadPool();
virtual ~CThreadPool();
bool Initialize( UINT cntThreads=1/*Default value*/,
UINT nMaxThreadCount= THREADPOOL_MAX_THREAD_COUNT,
UINT nMaxTaskCount= THREADPOOL_MAX_TASK_COUNT );/*线程池初始化函数*/
void Uninitialize();/*线程池销毁函数*/
bool AssignTask(PTHREAD_POOL_TASK pTask);/*添加任务函数*/
void WorkerThreadProc();/*线程回调函数*/

private:
UINT m_cntRemove;
UINT m_cntMaxThread; /*最大线程个数*/
UINT m_cntMaxTasks; /*最大工作函数个数*/

private:
UINT m_iLeisureThreadCount;
UINT m_iUnsettledTaskCount;
void NotifyAll(UINT nMsg, WPARAM wParam, LPARAM lParam);/*截获系统消息,销毁线程池*/
void FreeThreadDataBlock(UINT ixThread);/*杀死线程*/
UINT GetMyThreadDataIndex();/*获取线程索引*/
void RemoveIfMarked();/*杀死被标记的线程*/
void MarkThreadsForDelete(UINT cntThrds);/*标记将要被杀死的线程*/
void AllocNewThreads(UINT cntThrds,unsigned int nFlag);/*分配一个新线程*/
};

#endif // !defined(AFX_THREADPOOL_H__653A92C6_53BE_42B9_90BD_26F5DC231A56__INCLUDED_)
ls443085074 2012-05-14
  • 打赏
  • 举报
回复
[C++]int[C++]
longteng 2012-05-10
  • 打赏
  • 举报
回复
线程池浅析及C++代码实现

  (1)什么是线程池

  线程池是一种多线程处理技术。线程池先创建好若干线程,并管理这些线程。当有新的任务到来时,将任务添加到一个已创建的空闲线程中执行。线程池所创建的线程优先级都是一样的,所以需要使用特定线程优先级的任务不宜使用线程池。

  (2)线程池的优点和应用

  线程池统一管理线程的方式减少了频繁创建和销毁线程的系统调度开销,很大程度上提高了服务器处理并发任务的性能。

  线程池适用于频繁的任务调度,如处理HTTP请求,任务多,并且任务周期小

  (3)C++代码实现

  #include "stdafx.h"

  #include "stdafx.h"

  #include <assert.h>

  #include <windows.h>

  #include <map>

  #include <iostream>

  using namespace std;

  class ITask

  {

  public:

  virtual void ProcessTask(void* pUser)=0;

  };

  //線程池

  class CThreadPool

  {

  public:

  class ThreadInfo

  {

  public:

  ThreadInfo() { m_hThread=0;m_bBusyWorking=false;}

  ThreadInfo(HANDLEhandle, boolbBusy) { m_hThread=handle; m_bBusyWorking=bBusy; }

  ThreadInfo(const ThreadInfo& info){ m_hThread=info.m_hThread; m_bBusyWorking=info.m_bBusyWorking;}

  HANDLE m_hThread;

  bool m_bBusyWorking;

  };

  typedef map<DWORD,ThreadInfo>ThreadInfoMap;

  typedef ThreadInfoMap::iterator Iterator_ThreadInfoMap;

  enum ThreadPoolStatus{ STATUS_BUSY, STATUS_IDLE,STATUS_NORMAL };

  public:

  CThreadPool()

  {

  InitializeCriticalSection(&m_CS);

  }

  virtual ~CThreadPool()

  {

  DeleteCriticalSection(&m_CS);

  }

  bool Start(unsigned short nStatic, unsigned short nMax)

  {

  if(nMax<nStatic)

  {

  assert(0);

  return false;

  }

  HANDLE hThread;

  DWORD nThreadId;

  m_nNumberOfStaticThreads=nStatic;

  m_nNumberOfTotalThreads=nMax;

  //lock the resource

  EnterCriticalSection(&m_CS);

  //create an IO port

  m_hMgrIoPort = CreateIoCompletionPort((HANDLE)INVALID_HANDLE_VALUE,NULL, 0, 0);

  hThread = CreateThread(

  NULL, // SD

  0, // initial stack size

  (LPTHREAD_START_ROUTINE)ManagerProc, // threadfunction

  (LPVOID)this, // thread argument

  0, // creationoption

  &nThreadId ); // thread identifier

  m_hMgrThread = hThread;

  //now we start these worker threads

  m_hWorkerIoPort = CreateIoCompletionPort((HANDLE)INVALID_HANDLE_VALUE,NULL, 0, 0);

  for(long n = 0; n < nStatic; n++)

  {

  hThread = CreateThread(

  NULL, // SD

  0, // initial stack size

  (LPTHREAD_START_ROUTINE)WorkerProc, // threadfunction

  (LPVOID)this, //thread argument

  0, //creation option

  &nThreadId );

  m_threadMap.insert(m_threadMap.end(),ThreadInfoMap::value_type(nThreadId,ThreadInfo(hThread, false)));

  }

  LeaveCriticalSection(&m_CS);

  return true;

  }

  void Stop(bool bHash = false)

  {

  EnterCriticalSection(&m_CS);

  ::PostQueuedCompletionStatus(m_hMgrIoPort, 0, 0, (OVERLAPPED*)0xFFFFFFFF);

  WaitForSingleObject(m_hMgrThread,INFINITE);

  CloseHandle(m_hMgrThread);

  CloseHandle(m_hMgrIoPort);

  //shut down all the worker threads

  UINT nCount=m_threadMap.size();

  HANDLE* pThread= new HANDLE[nCount];

  long n=0;

  ThreadInfo info;

  Iterator_ThreadInfoMap i=m_threadMap.begin();

  while(i!=m_threadMap.end())

  {

  ::PostQueuedCompletionStatus(m_hWorkerIoPort, 0, 0, (OVERLAPPED*)0xFFFFFFFF);

  info=i->second;

  pThread[n++]=info.m_hThread;

  i++;

  }

  DWORD rc=WaitForMultipleObjects(nCount,pThread, TRUE,30000);//wait for 0.5 minutes, then start to killthreads

  CloseHandle(m_hWorkerIoPort);

  if(rc>=WAIT_OBJECT_0 && rc<WAIT_OBJECT_0+nCount)

  {

  for(unsigned int n=0;n<nCount;n++)

  {

  CloseHandle(pThread[n]);

  }

  }

  else if(rc==WAIT_TIMEOUT&&bHash)

  {

  //some threadsnot terminated, we have to stop them.

  DWORD exitCode;

  for(unsigned int i=0; i<nCount; i++)

  {

  if (::GetExitCodeThread(pThread[i],&exitCode)==STILL_ACTIVE)

  {

  TerminateThread(pThread[i], 99);

  }

  CloseHandle(pThread[i]);

  }

  }

  delete[] pThread;

  LeaveCriticalSection(&m_CS);

  }

  void AddTask(void* pUser, ITask* pWorker)const

  {

  ::PostQueuedCompletionStatus(m_hWorkerIoPort, \

  reinterpret_cast<DWORD>(pWorker), \

  reinterpret_cast<DWORD>(pUser),\

  NULL);

  }

  protected:

  HANDLE GetMgrIoPort()const { return m_hMgrIoPort; }

  UINT GetMgrWaitTime()const { return1000; }

  HANDLE GetWorkerIoPort()const { return m_hWorkerIoPort; }

  private:

  static DWORD WINAPI WorkerProc(void* p)

  {

  //convert the parameter to the server pointer.

  CThreadPool* pServer=(CThreadPool*)p;

  HANDLE IoPort = pServer->GetWorkerIoPort();

  unsigned long pN1,pN2;

  OVERLAPPED* pOverLapped;

  DWORD threadId=::GetCurrentThreadId();

  while(::GetQueuedCompletionStatus(IoPort, &pN1,&pN2,

  &pOverLapped, INFINITE))

  {

  if(pOverLapped ==(OVERLAPPED*)0xFFFFFFFE)

  {

  pServer->RemoveThread(threadId);

  break;

  }

else if(pOverLapped == (OVERLAPPED*)0xFFFFFFFF)

  {

  break;

  }

  else

  {

  pServer->SetStatus(threadId, true);

  //retrieve the job description and agent pointer

  ITask* pTask = reinterpret_cast<ITask*>(pN1);

  void* pUser= reinterpret_cast<void*>(pN2);

  pTask->ProcessTask(pUser);

  pServer->SetStatus(threadId, false);

  }

  }

  return 0;

  }

  static DWORD WINAPI ManagerProc(void* p)

  {

  //convert the parameter to the server pointer.

  CThreadPool* pServer=(CThreadPool*)p;

  HANDLE IoPort = pServer->GetMgrIoPort();

  unsigned long pN1,pN2;

  OVERLAPPED* pOverLapped;

  LABEL_MANAGER_PROCESSING:

  while(::GetQueuedCompletionStatus(IoPort, &pN1,&pN2,

  &pOverLapped, pServer->GetMgrWaitTime() ))

  {

  if(pOverLapped ==(OVERLAPPED*)0xFFFFFFFF)

  {

  return 0;

  }

  }

  //time out processing

  if (::GetLastError()==WAIT_TIMEOUT)

  {

  //the manager will take a look at all the worker's status.The

  if (pServer->GetStatus()==STATUS_BUSY)

  pServer->AddThreads();

  if (pServer->GetStatus()==STATUS_IDLE)

  pServer->RemoveThreads();

  goto LABEL_MANAGER_PROCESSING;

  }

  return 0;

  }

  protected:

  //manager thread

  HANDLE m_hMgrThread;

  HANDLE m_hMgrIoPort;

  protected:

  //configuration parameters

  mutable unsigned short m_nNumberOfStaticThreads;

  mutable unsigned short m_nNumberOfTotalThreads;

  protected:

  //helper functions

  void CThreadPool::AddThreads()

  {

  HANDLE hThread;

  DWORD nThreadId;

  unsigned int nCount=m_threadMap.size();

  unsigned int nTotal=min(nCount+2, m_nNumberOfTotalThreads);

  for(unsigned int i=0; i<nTotal-nCount; i++)

  {

  hThread = CreateThread(

  NULL, // SD

  0, // initial stack size

  (LPTHREAD_START_ROUTINE)WorkerProc, // threadfunction

  (LPVOID)this, //thread argument

  0, //creation option

  &nThreadId );

  m_threadMap.insert(m_threadMap.end(),ThreadInfoMap::value_type(nThreadId,ThreadInfo(hThread, false)));

  }

  }

  void RemoveThreads()

  {

  unsigned int nCount=m_threadMap.size();

  unsigned int nTotal=max(nCount-2, m_nNumberOfStaticThreads);

  for(unsigned int i=0; i<nCount-nTotal; i++)

  {

  ::PostQueuedCompletionStatus(m_hWorkerIoPort, 0, 0, (OVERLAPPED*)0xFFFFFFFE);

  }

  }

  ThreadPoolStatus GetStatus()

  {

  int nTotal = m_threadMap.size();

  ThreadInfo info;

  int nCount=0;

  Iterator_ThreadInfoMap i=m_threadMap.begin();

  while(i!=m_threadMap.end())

  {

  info=i->second;

  if (info.m_bBusyWorking==true)nCount++;

  i++;

  }

  if ( nCount/(1.0*nTotal) > 0.8 )

  return STATUS_BUSY;

  if ( nCount/ (1.0*nTotal) < 0.2 )

  return STATUS_IDLE;

  return STATUS_NORMAL;

  }

  void SetStatus(DWORD threadId,bool status)

  {

  EnterCriticalSection(&m_CS);

  Iterator_ThreadInfoMap i;

  ThreadInfo info;

  i=m_threadMap.find(threadId);

  info=i->second;

  info.m_bBusyWorking=status;

  m_threadMap.insert(m_threadMap.end(),ThreadInfoMap::value_type(threadId, info));

  LeaveCriticalSection(&m_CS);

  }

  void CThreadPool::RemoveThread(DWORDthreadId)

  {

  EnterCriticalSection(&m_CS);

  m_threadMap.erase(threadId);

  LeaveCriticalSection(&m_CS);

  }

  protected:

  //all the work threads

  ThreadInfoMap m_threadMap;

  CRITICAL_SECTION m_CS;

  HANDLE m_hWorkerIoPort;

  };

  ////////////////////測試代碼////////////////////////////////////

  class CTest:public ITask

  {

  public:

  CTest()

  {

  static int ii = 0;

  m_ii = ii ++;

  }

  void ProcessTask(void* pUser)

  {

  for(int i = 0; i <3; i ++)

  {

  cout<<"TaskID: "<<((CTest*)pUser)->m_ii<<endl;

  Sleep(100);

  }

  }

  ~CTest()

  {

  }

  private:

  int m_ii;

  };

  int _tmain(int argc, _TCHAR* argv[])

  {

  CThreadPool *pPool= new CThreadPool();

  const int TEST_COUNT = 8;

  CTest test[TEST_COUNT];

  //啟動線程池,5個處理線程,最多接受10個任務

  pPool->Start(5,10);

  //添加任務到線程池中

  for(int i = 0; i < TEST_COUNT; i++)

  pPool->AddTask(&test[i], &test[i]);

  cin.get();

  //停止線程池

  pPool->Stop();

  return 0;

  }
ziplj 2010-01-18
  • 打赏
  • 举报
回复
Windows有一个自带的线程池
有点在哪? -- 网上一堆评论吧 你能知道有线程池 就应该已经知道了线程池的好处了

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧