//////////////////////////////////////////////////////////////////////////// // CThreadPool クラスのインタフェース宣言 // //////////////////////////////////////////////////////////////////////////// #include #include "ThreadPool.h" #include "DmyThread.h" //////////////////////////////////////////////////////////////////////////// // 構築・破棄 CThreadPool::CThreadPool() : semaGate( 0 ), ThCounter( 0 ), pExThread( NULL ), semaExThread( 1 ), ExitFlg( false ), semaExit( 1 ) { } CThreadPool::~CThreadPool() { int i; ExitFlg = true; for ( i = 0; i < vThread.size(); i++ ) { semaExit.P(); // プールされているスレッドを一つ走らせる semaGate.V(); // 走らせたスレッドが終了するのを待つ semaExit.P(); semaExit.V(); } // スレッドが完全に終了するまで待ち合わせ // スレッドオブジェクトを破棄する for ( i = 0; i < vThread.size(); i++ ) { vThread[i]->Wait(); delete vThread[i]; vThread[i] = NULL; } vThread.clear(); } //////////////////////////////////////////////////////////////////////////// // メソッド // スレッドを使用する bool CThreadPool::run( CDmyThread *pThread ) { semaExThread.P(); if ( vThread.size() == ThCounter ) { if ( !AddThread() ) { semaExThread.V(); return false; } } pExThread = pThread; semaGate.V(); return true; } // プールにスレッドを追加する bool CThreadPool::AddThread() { int i, j; // 新たに追加するスレッドの数を決定 if ( vThread.size() == 0 ) j = 10; // 初期状態では10個 else j = vThread.size(); // スレッドを生成する for ( i = 0; i < j; i++ ) { CPooledThread *p = new CPooledThread( this ); if ( NULL == p ) return false; p->start(); vThread.push_back( p ); } return true; } // スレッドのたまり場 void CThreadPool::WaitNextJob( CThread *pTh ) { CDmyThread *wp; while ( -1 ) { // 待ち合わせる semaGate.P(); if ( ExitFlg ) break; if ( NULL == pExThread ) { // することがなかった continue; } ThCounter--; wp = pExThread; semaExThread.V(); // 仕事を行う wp->OnStart( pTh ); wp->run(); wp->OnExit(); } semaExit.V(); }