/**/ /// ===========================================================================/// 文件: NCThread.h/// 作者: hjbcn/// 时间: 2006-12-18/// ---------------------------------------------------------------------------/// [class] NCThread/// [class] NCThreadPool/// ---------------------------------------------------------------------------/// /// =========================================================================== #pragma once #include < vector > using namespace std; struct tagNCThreadParam; class NCThread; class NCThreadPool;typedef struct tagNCThreadParam ... { HANDLE hTerminateEvent; LPDWORD lpdwTerminateFlag; LPVOID lpParam;} NCThreadParam , * PNCThreadParam; class NCThread ... { friend class NCThreadPool;public: enum NCThreadStatus ...{ STATUS_STOPPED = 1 , STATUS_RUNNING = 2 , STATUS_PAUSED = 3 };public: NCThread( LPTHREAD_START_ROUTINE fpThreadMain ); ~NCThread( void );public: DWORD Start( LPVOID lpParam ); DWORD Stop( DWORD dwWaitTick = INFINITE ); void Pause( void ); void Continue( void );protected: LPTHREAD_START_ROUTINE m_fpThreadMain; HANDLE m_hThread; DWORD m_dwThreadStatus; DWORD m_bTerminateFlag; HANDLE m_hTerminateEvent; NCThreadParam m_zThreadParam;} ;typedef NCThread * PNCThread;DWORD WINAPI TR_THREAD_POOL_KEEPER( LPVOID lpParam ); class NCThreadPool ... { friend DWORD WINAPI TR_THREAD_POOL_KEEPER( LPVOID lpParam );public: NCThreadPool( void ); ~NCThreadPool( void );public: PNCThread Add( LPTHREAD_START_ROUTINE fpThreadMain , LPVOID lpParam ); DWORD Count();protected: PNCThread m_keeper; HANDLE m_hAddEvent; vector< HANDLE > m_vThreadHandles; vector< PNCThread > m_vThreads; RTL_CRITICAL_SECTION m_rcs;} ;typedef NCThreadPool * PNCThreadPool; /**/ /// ===========================================================================/// 文件: NCThread.cpp/// 作者: hjbcn/// 时间: 2006-12-18/// =========================================================================== #include " StdAfx.h " #include " NCThread.h " NCThread::NCThread( LPTHREAD_START_ROUTINE fpThreadMain ) ... { m_fpThreadMain = fpThreadMain; m_hThread = INVALID_HANDLE_VALUE; m_dwThreadStatus = STATUS_STOPPED; m_bTerminateFlag = FALSE; m_hTerminateEvent = ::CreateEvent( NULL , FALSE , FALSE , NULL ); ::ZeroMemory( &m_zThreadParam , sizeof(NCThreadParam) );} NCThread:: ~ NCThread( void ) ... { Stop( INFINITE ); ::CloseHandle( m_hTerminateEvent ); m_hTerminateEvent = INVALID_HANDLE_VALUE;} DWORD NCThread::Start( LPVOID lpParam ) ... { DWORD tid = 0; if( INVALID_HANDLE_VALUE != m_hThread ) ...{ return 0; } m_bTerminateFlag = FALSE; ::ResetEvent( m_hTerminateEvent ); m_zThreadParam.hTerminateEvent = m_hTerminateEvent; m_zThreadParam.lpdwTerminateFlag = &m_bTerminateFlag; m_zThreadParam.lpParam = lpParam; m_hThread = ::CreateThread( NULL , 0 , m_fpThreadMain , &m_zThreadParam , 0 , &tid ); if( m_hThread ) ...{ m_dwThreadStatus = STATUS_RUNNING; } return tid;} DWORD NCThread::Stop( DWORD dwWaitTick ) ... { DWORD exitCode = -1; BOOL ret = FALSE; DWORD waitRet = -1; if( INVALID_HANDLE_VALUE == m_hThread ) ...{ return 0x36518; } m_bTerminateFlag = TRUE; ::SetEvent( m_hTerminateEvent ); ret = ::GetExitCodeThread( m_hThread , &exitCode ); if( !ret || STILL_ACTIVE == exitCode ) ...{ waitRet = ::WaitForSingleObject( m_hThread , dwWaitTick ); if( WAIT_OBJECT_0 != waitRet ) ...{ ::TerminateThread( m_hThread , 0x36518 ); } } ret = ::GetExitCodeThread( m_hThread , &exitCode ); if( !ret ) ...{ exitCode = 0x36518; } m_dwThreadStatus = STATUS_STOPPED; ::CloseHandle( m_hThread ); m_hThread = INVALID_HANDLE_VALUE; return exitCode;} void NCThread::Pause( void ) ... { DWORD ret = 0; if( !m_hThread ) ...{ return; } if( m_dwThreadStatus != STATUS_RUNNING ) ...{ return; } ret = ::SuspendThread( m_hThread ); if( (DWORD)-1 != ret ) ...{ m_dwThreadStatus = STATUS_PAUSED; }} void NCThread::Continue( void ) ... { DWORD ret = 0; if( !m_hThread ) ...{ return; } if( m_dwThreadStatus != STATUS_PAUSED ) ...{ return; } ret = ::ResumeThread( m_hThread ); if( (DWORD)-1 != ret ) ...{ m_dwThreadStatus = STATUS_RUNNING; }} DWORD WINAPI TR_THREAD_POOL_KEEPER( LPVOID lpParam ) ... { PNCThreadParam param = (PNCThreadParam)lpParam; PNCThreadPool ptpool = (PNCThreadPool)param->lpParam; vector< HANDLE > vEvents; vector< HANDLE >::iterator vpHandle; vector< PNCThread >::iterator vpThread; DWORD dwRet = 0; DWORD dwExitRet = 0; while( !*(param->lpdwTerminateFlag) ) ...{ vEvents.clear(); vEvents.push_back( param->hTerminateEvent ); vEvents.push_back( ptpool->m_hAddEvent ); ::EnterCriticalSection( &ptpool->m_rcs ); vEvents.insert( vEvents.end() , ptpool->m_vThreadHandles.begin() , ptpool->m_vThreadHandles.end() ); ::LeaveCriticalSection( &ptpool->m_rcs ); dwRet = ::WaitForMultipleObjects( (DWORD)vEvents.size() , &vEvents[0] , FALSE , 1000*60*5 ); switch( dwRet ) ...{ case WAIT_TIMEOUT: break; case WAIT_OBJECT_0: break; case WAIT_OBJECT_0+1: break; case WAIT_FAILED: ...{ size_t offset = 0; size_t vsize = vEvents.size(); for( size_t i = 0 ; i < vsize-2 ; i++ ) ...{ dwRet = ::GetExitCodeThread( ptpool->m_vThreadHandles[offset] , &dwExitRet ); if( STILL_ACTIVE != dwExitRet ) ...{ ::EnterCriticalSection( &ptpool->m_rcs ); delete ptpool->m_vThreads[offset]; ptpool->m_vThreads.erase( ptpool->m_vThreads.begin() + offset ); ptpool->m_vThreadHandles.erase( ptpool->m_vThreadHandles.begin() + offset ); ::LeaveCriticalSection( &ptpool->m_rcs ); } else ...{ ++offset; } } } break; default: ...{ DWORD offset = dwRet - (WAIT_OBJECT_0+2); ::EnterCriticalSection( &ptpool->m_rcs ); delete ptpool->m_vThreads[offset]; ptpool->m_vThreads.erase( ptpool->m_vThreads.begin() + offset ); ptpool->m_vThreadHandles.erase( ptpool->m_vThreadHandles.begin() + offset ); ::LeaveCriticalSection( &ptpool->m_rcs ); } break; } } return 0;} NCThreadPool::NCThreadPool( void ) ... { ::InitializeCriticalSection( &m_rcs ); m_hAddEvent = ::CreateEvent( NULL , FALSE , FALSE , NULL ); m_keeper = new NCThread( TR_THREAD_POOL_KEEPER ); m_keeper->Start( this );} NCThreadPool:: ~ NCThreadPool( void ) ... { m_keeper->Stop( 2000 ); delete m_keeper; if( m_hAddEvent ) ...{ ::CloseHandle( m_hAddEvent ); } ::DeleteCriticalSection( &m_rcs );} PNCThread NCThreadPool::Add( LPTHREAD_START_ROUTINE fpThreadMain , LPVOID lpParam ) ... { PNCThread pNewThread = new NCThread( fpThreadMain ); DWORD tid = pNewThread->Start( lpParam ); if( pNewThread->m_hThread ) ...{ ::EnterCriticalSection( &m_rcs ); m_vThreadHandles.push_back( pNewThread->m_hThread ); m_vThreads.push_back( pNewThread ); ::SetEvent( m_hAddEvent ); ::LeaveCriticalSection( &m_rcs ); } return pNewThread;} DWORD NCThreadPool::Count() ... { DWORD size = 0; ::EnterCriticalSection( &m_rcs ); size = (DWORD)m_vThreadHandles.size(); ::LeaveCriticalSection( &m_rcs ); return size;} // NCLIB.cpp : 定义控制台应用程序的入口点。 // #include " stdafx.h " #include " NCThread.h " DWORD WINAPI printer( LPVOID lpParam ) ... { PNCThreadParam param = (PNCThreadParam)lpParam; char* str = (char*)param->lpParam; for( int i = 0 ; i < 1 ; i++ ) ...{ printf( "%d : %s " , ::GetCurrentThreadId() , str ); } return 0;} void test_case_01() ... { NCThreadPool threadMan; char msg[1024] = ...{ 0 }; strcpy( msg , "hello,world." ); for( int i = 0 ; i < 50 ; i++ ) ...{ threadMan.Add( printer , msg ); } while( threadMan.Count() > 0 ) Sleep( 1000 );} int _tmain( int argc, _TCHAR * argv[]) ... { test_case_01(); printf( "---------------- " ); for( int i = 1 ; i < 10 ; i++ ) ...{ test_case_01(); printf( "---------------- " ); } printf( "press any key to continue... " ); return 0;}