multithread in C++ with Windows
Windowsのスレッド関係のAPIのラッパクラスを書いてみた。こんなことしなくてもpthreadやboost::threadあたり使えばいいんだけど、勉強のために。
#include <windows.h> #include <cassert> #include <process.h> namespace multithread { typedef unsigned (__stdcall * thread_func_t)(void *); // thread ---------------------------------------------------------------- class thread { HANDLE m_handle; unsigned m_id; unsigned m_stack_size; public: // stack_sizeが0==1MB(Windowsの規定) thread(unsigned stack_size = 0) : m_handle(0), m_id(0), m_stack_size(stack_size) {} ~thread() { if(!!m_handle) CloseHandle(m_handle); } // 上手く実行できた場合、 // または既に実行/生成している場合true bool start(thread_func_t thread_func, void * thread_arg) { if(!m_handle) { m_handle = reinterpret_cast<HANDLE> ( _beginthreadex( NULL, m_stack_size, thread_func, thread_arg, 0, &m_id ) ); if(m_handle==0) return false; } return true; } // 上手く生成できた場合、 // または既に実行/生成している場合true bool materialize(thread_func_t thread_func, void * thread_arg) { if(!m_handle) { m_handle = reinterpret_cast<HANDLE> ( _beginthreadex( NULL, m_stack_size, thread_func, thread_arg, CREATE_SUSPENDED, &m_id ) ); if(m_handle==0) return false; } return true; } // 情報取得 // スレッドが生成済み/走っている場合true operator bool() { unsigned long result; return !!m_handle && (GetExitCodeThread(m_handle, &result)!=0) && (result==STILL_ACTIVE); } const unsigned id() { return m_id; } const int exitcode() const { unsigned long result; if(GetExitCodeThread(m_handle, &result)!=0) return result; } void priority(int new_priority) const { assert(-7 <= new_priority && new_priority < 7); SetThreadPriority(m_handle, new_priority); } const int priority() const { return GetThreadPriority(m_handle); } // 操作 const unsigned suspend() const { return SuspendThread(m_handle); } const unsigned resume() const { return ResumeThread(m_handle); } void wait(const unsigned long time = INFINITE) const { WaitForSingleObject(m_handle, time); } private: thread(const thread &); const thread & operator=(const thread &); }; }
っていうか_beginthreadと_beginthreadexでインターフェイスやハンドルの後始末の方法とかが違うし、_MTマクロを定義(もしくはプロジェクト->設定でいじる)しないと使えないしでCreateThreadが恋しくなるんだけどなぁ…。VCのCRTライブラリ関係は腐っている、と解釈していいんだろうか?
critical sectionに関してはこれで。