[Win32] [线程] [NCThread] [NCThreadPool] 线程类、线程管理类

 

/// ===========================================================================
/// 文件: 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;

    
forint 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." );
    
forint 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( 
"---------------- " );
    
forint i = 1 ; i < 10 ; i++ )
    
{
        test_case_01();
        printf( 
"---------------- " );
    }


    printf( 
"press any key to continue... " );
    
return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值