クリティカルセクション †Win32 でスレッドの同期をする多くの場合に使われるのがクリティカルセクション。 InitializeCriticalSection() でオブジェクトを作成して、 EnterCriticalSection() で所有権を取得して、 LeaveCriticalSection() で所有権を破棄して、 DeleteCriticalSection() でオブジェクトを破棄する。 InitializeCriticalSection?() と DeleteCriticalSection?() は、 およその場合、アプリケーションの開始時と終了時にやれば良い。 頻繁に使うのが EnterCriticalSection?() と LeaveCriticalSection?() で、 これを一々呼び出すのが著しく面倒だし、 ヘタするとロック解除するのを忘れたりしてバグの元になる。 そんなアナタに便利なマクロ。 class CriticalSectionHelper
{
public:
CriticalSectionHelper( LPCRITICAL_SECTION p )
: m_pCS( p )
{
::EnterCriticalSection( m_pCS );
}
~CriticalSectionHelper() {
::LeaveCriticalSection( m_pCS );
}
private:
LPCRITICAL_SECTION m_pCS;
};
#define CS_LOCK(p) CriticalSectionHelper cs(p)
排他制御したい処理をブロック ({}) で囲んで、 その先頭行にこのマクロを書けばOK。 CRITICAL_SECTION cs; ::InitializeCriticalSection( &cs ); {
CS_LOCK( &cs );
// ここに排他したい処理を記述。
}
関数自体を排他したければ、その関数の先頭にこのマクロを書いておけば良い。 |