【发布时间】:2012-08-26 06:45:39
【问题描述】:
我最近一直在研究我自己的线程池实现,它运行良好(几乎)。问题是它占用了几乎所有的 CPU 资源。 请看一下我的实现:
ThreadPool.h
#include <vector>
#include <list>
#include <Windows.h>
const int DefaultThreadsNumber = 5;
class thread_pool
{
typedef void ( *Task )( );
void* m_hEvent;
CRITICAL_SECTION m_hExecuteFunc;
CRITICAL_SECTION m_hRunFunc;
std::vector<void*> m_ThreadHandles;
std::list<Task> m_TasksQueue;
int m_nThreadInQueue;
static unsigned __stdcall Run( void* thisParam );
public:
thread_pool( int nMaxThreadNo );
~thread_pool();
void Execute( Task task );
};
ThreadPool.cpp
#include "thread_pool.h"
#include <process.h>
void* g_hTaskFinishedEvent;
thread_pool::thread_pool( int nMaxThreadNo )
{
if ( nMaxThreadNo <= 0 )
nMaxThreadNo = DefaultThreadsNumber;
m_nThreadInQueue = nMaxThreadNo;
for( int i = 0; i < nMaxThreadNo; ++i )
{
m_ThreadHandles.push_back((void*)_beginthreadex(NULL, 0, &Run, (void*)this, 0, 0 ));
}
InitializeCriticalSection( &m_hExecuteFunc );
InitializeCriticalSection( &m_hRunFunc );
}
thread_pool::~thread_pool()
{
for ( std::vector<void*>::iterator it = m_ThreadHandles.begin();
it != m_ThreadHandles.end();
++it )
{
CloseHandle( *it );
}
DeleteCriticalSection( &m_hExecuteFunc );
DeleteCriticalSection( &m_hRunFunc );
}
void thread_pool::Execute( Task task )
{
EnterCriticalSection( &m_hExecuteFunc );
m_TasksQueue.push_back( task );
LeaveCriticalSection( &m_hExecuteFunc );
m_hEvent = CreateEvent(NULL, true, false, NULL);
SetEvent( m_hEvent ); // TODO: what if setEvent will fail???
}
unsigned __stdcall thread_pool::Run(void* thisParam )
{
thread_pool *This = (thread_pool*)thisParam;
while(true)
{
WaitForSingleObject( This->m_hEvent, INFINITE );
while(!This->m_TasksQueue.empty())
{
EnterCriticalSection( &This->m_hExecuteFunc );
if ( !This->m_TasksQueue.empty() )
{
This->m_TasksQueue.front()();
This->m_TasksQueue.pop_front();
g_hTaskFinishedEvent = CreateEvent(NULL, true, false, NULL);
SetEvent( g_hTaskFinishedEvent );
}
LeaveCriticalSection( &This->m_hExecuteFunc );
}
}
return 0;
}
如何改进?
提前致谢。
【问题讨论】:
-
单步执行占用 100% CPU 的代码。您应该很快就能找到问题所在。
-
什么时候占用所有CPU?什么时候没有线程可以运行?这可能是因为您等待
m_hEvent,但在调用Execute之前不初始化它。我不知道WaitForSingleObject在使用非法事件句柄调用时会做什么。 -
您的代码还存在其他设计问题,例如将
this传递给您创建的所有线程,这意味着所有线程将使用相同thisParam。跨度> -
还要确保提供线程函数的退出路径,CloseHandle 不会终止线程。
-
Joachim Pileborg - 传递这个只是为了在单独的线程中运行类方法。加上程序中只使用了一个 threadPool 实例,所以我在考虑将这个类设为单例还是不是一个好主意?
标签: c++ winapi threadpool