dcdd144598 2011-02-23 kinaba: #ifndef _KILIB_THREAD_H_ dcdd144598 2011-02-23 kinaba: #define _KILIB_THREAD_H_ dcdd144598 2011-02-23 kinaba: #include "types.h" dcdd144598 2011-02-23 kinaba: #ifndef __ccdoc__ dcdd144598 2011-02-23 kinaba: namespace ki { dcdd144598 2011-02-23 kinaba: #endif dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //========================================================================= dcdd144598 2011-02-23 kinaba: //@{ @pkg ki.Core //@} dcdd144598 2011-02-23 kinaba: //@{ dcdd144598 2011-02-23 kinaba: // マルチスレッドの管理 dcdd144598 2011-02-23 kinaba: // dcdd144598 2011-02-23 kinaba: // まだ何もしません dcdd144598 2011-02-23 kinaba: //@} dcdd144598 2011-02-23 kinaba: //========================================================================= dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: class ThreadManager dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: public: dcdd144598 2011-02-23 kinaba: //@{ 実行可能オブジェクトをに起動をかける //@} dcdd144598 2011-02-23 kinaba: void Run( class Runnable& r ); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 複数スレッドが走っているかどうか? //@} dcdd144598 2011-02-23 kinaba: bool isMT() const; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: private: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: ThreadManager(); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: private: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: int threadNum_; dcdd144598 2011-02-23 kinaba: static ThreadManager* pUniqueInstance_; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: private: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: static DWORD WINAPI ThreadStubFunc(void*); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: private: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: friend void APIENTRY Startup(); dcdd144598 2011-02-23 kinaba: friend inline ThreadManager& thd(); dcdd144598 2011-02-23 kinaba: NOCOPY(ThreadManager); dcdd144598 2011-02-23 kinaba: }; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //------------------------------------------------------------------------- dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //@{ 唯一のスレッド管理オブジェクトを返す //@} dcdd144598 2011-02-23 kinaba: inline ThreadManager& thd() dcdd144598 2011-02-23 kinaba: { return *ThreadManager::pUniqueInstance_; } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: inline bool ThreadManager::isMT() const dcdd144598 2011-02-23 kinaba: { return 0 != threadNum_; } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //========================================================================= dcdd144598 2011-02-23 kinaba: //@{ dcdd144598 2011-02-23 kinaba: // 実行可能オブジェクト基底 dcdd144598 2011-02-23 kinaba: //@} dcdd144598 2011-02-23 kinaba: //========================================================================= dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: class Runnable dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: protected: dcdd144598 2011-02-23 kinaba: Runnable(); dcdd144598 2011-02-23 kinaba: virtual ~Runnable(); dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: virtual void StartThread() = 0; dcdd144598 2011-02-23 kinaba: void PleaseExit(); dcdd144598 2011-02-23 kinaba: bool isExitRequested() const; dcdd144598 2011-02-23 kinaba: bool isRunning() const; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: private: dcdd144598 2011-02-23 kinaba: void FinalizeThread(); dcdd144598 2011-02-23 kinaba: friend class ThreadManager; dcdd144598 2011-02-23 kinaba: HANDLE hEvent_; dcdd144598 2011-02-23 kinaba: HANDLE hThread_; dcdd144598 2011-02-23 kinaba: }; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //========================================================================= dcdd144598 2011-02-23 kinaba: //@{ dcdd144598 2011-02-23 kinaba: // マルチスレッド・ポリシー1 dcdd144598 2011-02-23 kinaba: // dcdd144598 2011-02-23 kinaba: // このクラスから派生すると、AutoLock クラスを使えるようになります。 dcdd144598 2011-02-23 kinaba: // このクラスに this ポインタを渡すことで排他状態に入り、デストラクタで dcdd144598 2011-02-23 kinaba: // 抜け出せるようになります。NoLockable::AutoLock は実際は何もしません。 dcdd144598 2011-02-23 kinaba: //@} dcdd144598 2011-02-23 kinaba: //========================================================================= dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: class NoLockable dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: protected: dcdd144598 2011-02-23 kinaba: struct AutoLock dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: AutoLock( NoLockable* host ) {} dcdd144598 2011-02-23 kinaba: }; dcdd144598 2011-02-23 kinaba: }; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //========================================================================= dcdd144598 2011-02-23 kinaba: //@{ dcdd144598 2011-02-23 kinaba: // マルチスレッド・ポリシー2 dcdd144598 2011-02-23 kinaba: // dcdd144598 2011-02-23 kinaba: // このクラスから派生すると、AutoLock クラスを使えるようになります。 dcdd144598 2011-02-23 kinaba: // このクラスに this ポインタを渡すことで排他状態に入り、デストラクタで dcdd144598 2011-02-23 kinaba: // 抜け出せるようになります。EzLockable::AutoLock は、シングルスレッドで dcdd144598 2011-02-23 kinaba: // 動作するときがほとんどというアプリケーション向けに、高速だけれど dcdd144598 2011-02-23 kinaba: // 不完全な排他制御を行います。2本目のスレッド立ち上げの瞬間が危ない。 dcdd144598 2011-02-23 kinaba: //@} dcdd144598 2011-02-23 kinaba: //========================================================================= dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: class EzLockable dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: protected: dcdd144598 2011-02-23 kinaba: EzLockable() dcdd144598 2011-02-23 kinaba: { ::InitializeCriticalSection( &csection_ ); } dcdd144598 2011-02-23 kinaba: ~EzLockable() dcdd144598 2011-02-23 kinaba: { ::DeleteCriticalSection( &csection_ ); } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: struct AutoLock dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: AutoLock( EzLockable* host ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: if( NULL != (pCs_=(thd().isMT() ? &host->csection_ : NULL)) ) dcdd144598 2011-02-23 kinaba: ::EnterCriticalSection( pCs_ ); dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: ~AutoLock() dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: if( pCs_ ) dcdd144598 2011-02-23 kinaba: ::LeaveCriticalSection( pCs_ ); dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: private: dcdd144598 2011-02-23 kinaba: NOCOPY(AutoLock); dcdd144598 2011-02-23 kinaba: CRITICAL_SECTION* pCs_; dcdd144598 2011-02-23 kinaba: }; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: private: dcdd144598 2011-02-23 kinaba: CRITICAL_SECTION csection_; dcdd144598 2011-02-23 kinaba: #ifdef __DMC__ dcdd144598 2011-02-23 kinaba: friend struct EzLockable::AutoLock; dcdd144598 2011-02-23 kinaba: #else dcdd144598 2011-02-23 kinaba: friend struct AutoLock; dcdd144598 2011-02-23 kinaba: #endif dcdd144598 2011-02-23 kinaba: }; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //========================================================================= dcdd144598 2011-02-23 kinaba: //@{ dcdd144598 2011-02-23 kinaba: // マルチスレッド・ポリシー3 dcdd144598 2011-02-23 kinaba: // dcdd144598 2011-02-23 kinaba: // このクラスから派生すると、AutoLock クラスを使えるようになります。 dcdd144598 2011-02-23 kinaba: // このクラスに this ポインタを渡すことで排他状態に入り、デストラクタで dcdd144598 2011-02-23 kinaba: // 抜け出せるようになります。Lockable::AutoLock は、完全な排他制御を dcdd144598 2011-02-23 kinaba: // 行います。万全を期すならかならずこのクラスを用いましょう。 dcdd144598 2011-02-23 kinaba: //@} dcdd144598 2011-02-23 kinaba: //========================================================================= dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: class Lockable dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: protected: dcdd144598 2011-02-23 kinaba: Lockable() dcdd144598 2011-02-23 kinaba: { ::InitializeCriticalSection( &csection_ ); } dcdd144598 2011-02-23 kinaba: ~Lockable() dcdd144598 2011-02-23 kinaba: { ::DeleteCriticalSection( &csection_ ); } dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: struct AutoLock dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: AutoLock( Lockable* host ) dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: pCs_ = &host->csection_; dcdd144598 2011-02-23 kinaba: ::EnterCriticalSection( pCs_ ); dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: ~AutoLock() dcdd144598 2011-02-23 kinaba: { dcdd144598 2011-02-23 kinaba: ::LeaveCriticalSection( pCs_ ); dcdd144598 2011-02-23 kinaba: } dcdd144598 2011-02-23 kinaba: private: dcdd144598 2011-02-23 kinaba: NOCOPY(AutoLock); dcdd144598 2011-02-23 kinaba: CRITICAL_SECTION* pCs_; dcdd144598 2011-02-23 kinaba: }; dcdd144598 2011-02-23 kinaba: friend struct AutoLock; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: private: dcdd144598 2011-02-23 kinaba: CRITICAL_SECTION csection_; dcdd144598 2011-02-23 kinaba: }; dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: //========================================================================= dcdd144598 2011-02-23 kinaba: dcdd144598 2011-02-23 kinaba: } // namespace ki dcdd144598 2011-02-23 kinaba: #endif // _KILIB_THREAD_H_