【问题标题】:Thread pool is is taking all CPU resources线程池正在占用所有 CPU 资源
【发布时间】: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


【解决方案1】:

在 CreateEvent 中,bManualReset 设置为 true,但您不会在任何地方调用 ResetEvent。因此,一旦发出信号,事件就会永远保持设置状态,并且 WaitForSingleObject 会立即返回。将其设为自动重置事件,或在所有工作人员完成后致电ResetEvent

【讨论】:

  • 另外,m_hEvent 不断被新事件覆盖。
猜你喜欢
  • 2013-01-02
  • 2022-01-16
  • 2018-08-17
  • 2021-09-04
  • 2019-10-27
  • 2021-07-03
  • 1970-01-01
  • 2018-08-02
  • 1970-01-01
相关资源
最近更新 更多