まずは、何もせずに純粋にスレッドの終了を待つサンプルを3つ用意しました。1つは最初のものを待機するように修正したものです。こちらは本当に待機せずという場合に、待機部分を必要なタイミングに持ち越すことでその時に待つことができるようになります。うまく活用すればかなり強力な仕組みが用意できます。
#include <process.h> void ThreadBusyLoopEx( DWORD dwTime ) { unsigned thrdaddr; HANDLE hThread = reinterpret_cast<HANDLE>( _beginthreadex( NULL, 0, BusyLoopThProcEx, &dwTime, 0, &thrdaddr ) ); if( hThread != NULL ){ // hTread をどこかに保持しておき、プログラム終了時に下記の処理を行えば、中途半端な状態で終わることはなくなる。 CSimpleWaitCursor wait; WaitForSingleObject( hThread, INFINITE ); CloseHandle( hThread ); } }
残り2つは、マルチスレッドサンプルでよく見る_beginthread版と、Visual Studio 2010で追加された同時実行ランタイムにある、軽量タスクというスレッドの簡素版を使った例です。どちらも呼び出し部分を相互に入れ替えて使うことができます。
最後の並列処理部分で改めて出てきますが、同時実行ランタイムを利用する場合は、軽量タスクの利用も検討してみてください。
#include <process.h> class CThreadParam { public: CThreadParam( DWORD dwTime ) : m_workTime( dwTime ) , m_event( CreateEvent( NULL, TRUE, FALSE, NULL ) ) { } ~CThreadParam() { if( m_event != NULL ){ CloseHandle( m_event ); } m_event = NULL; } public: DWORD m_workTime; HANDLE m_event; }; void _cdecl BusyLoopThProc( void* param ) { CThreadParam* pParam = static_cast( param ); DWORD dwStart = GetTickCount(); while( (GetTickCount()-dwStart) < pParam->m_workTime ); SetEvent( pParam->m_event ); } void ThreadBusyLoop( DWORD dwTime ) { CThreadParam param( dwTime ); if( param.m_event != NULL ){ uintptr_t nResult = _beginthread( BusyLoopThProc, 0, ¶m ); if( nResult != -1 ){ CSimpleWaitCursor wait; WaitForSingleObject( param.m_event, INFINITE ); } } }
#include <ppl.h> class CThreadParamPPL { public: CThreadParamPPL( DWORD dwTime ) : m_workTime( dwTime ) { m_event.reset(); } public: DWORD m_workTime; Concurrency::event m_event; }; void _cdecl BusyLoopThProcPPL( void* param ) { CThreadParamPPL* pParam = static_cast( param ); DWORD dwStart = GetTickCount(); while( (GetTickCount()-dwStart) < pParam->m_workTime ); pParam->m_event.set(); } void ThreadBusyLoopPPL( DWORD dwTime ) { CThreadParamPPL param( dwTime ); CSimpleWaitCursor wait; Concurrency::CurrentScheduler::ScheduleTask( BusyLoopThProcPPL, ¶m ); param.m_event.wait(); }
並列処理を簡素に導入できる同時実行ランタイムですが、現在メモリーリークするという不具合を抱えています。
もし、この記事を見て早く直した方がいいと思う人がいたら、上記リンクより、重要であると投票をお願いします。また、再現サンプルを利用するなどで再現できるという場合は、再現できたという部分にも投票してもらえると、MSも需要が高いとみなし優先的に修正対象にしてくれると思います。