社区
进程/线程/DLL
帖子详情
C++线程池如何实现?有什么好处?谁有源码?
tech_study_00
2010-01-18 04:45:59
C++线程池的优点在哪里?
谁有相关代码?
...全文
1320
15
打赏
收藏
C++线程池如何实现?有什么好处?谁有源码?
C++线程池的优点在哪里? 谁有相关代码?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
15 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
lijianli9
2012-05-22
打赏
举报
回复
建议lz看下windows核心编程 讲解线程的几个章节,以及win32多线程程序设计,先回用线程,然后再深入研究,
Eleven
2012-05-21
打赏
举报
回复
http://msdn.microsoft.com/en-us/library/39f8fee2(VS.80).aspx
Eleven
2012-05-21
打赏
举报
回复
http://blog.csdn.net/flowshell/article/details/4674689
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有一个自带的线程池
有点在哪? -- 网上一堆评论吧 你能知道有线程池 就应该已经知道了线程池的好处了
c++
线程池
的
实现
代码
这是一个使用
c++
实现
的
线程池
的源代码,在WIN以及UNIX环境下都可以使用
C++
线程池
源码
一个工作队列,有些类似
线程池
,可以很好扩展。
C++
百万并发网络通信引擎架构与
实现
(Socket、全栈、跨平台) Version 1.0
从基础的网络知识开始由浅入深地讲解如何使用
C++
实现
一套支持百万级别并发的网络通信引擎。包含:高频并发、多线程、多进程、
线程池
、内存池、软件硬件瓶颈、如何测试优化网络处理能力等技术知识。可以应用在Windows...
C++
线程池
源码
+demo _android
源码
分析
分享一个游戏项目中的封装
C++
线程池
源码
分别用C98,C11语法
实现
了下,包含了测试用例
c++
实现
的
线程池
源码
.rar
使用
线程池
可以很好地提高性能,
线程池
在系统启动时即创建大量空闲的线程,程序将一个任务传给
线程池
,
线程池
就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回
线程池
中成为空闲状态,...
进程/线程/DLL
15,471
社区成员
49,182
社区内容
发帖
与我相关
我的任务
进程/线程/DLL
VC/MFC 进程/线程/DLL
复制链接
扫一扫
分享
社区描述
VC/MFC 进程/线程/DLL
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章