Win32並行処理プログラミング入門38
ミューテックス・カーネルオブジェクトとは、スレッドが1つの共有リソース、もしくはコード片に、排他的にアクセスできるようにする同期オブジェクトです。
排他的なアクセスとは、1つのスレッドがアクセスしている間、他のスレッドがアクセス出来ないという事です。並行処理時には、複数のスレッドが1つの共有リソースもしくはコード片にアクセスする事を許すと、正しい結果が得られなくなりますので、排他的にアクセスする同期オブジェクトが必要となります。
この説明を読むと難しく感じるかもしれませんが、ミューテックス・カーネルオブジェクトの使用方法は非常に簡単です。前回掲載したサンプルを用いて、ミューテックス・カーネルオブジェクトに関する関数の解説をします。
//ミューテックスの初期化と破棄が必要
ConcurrentFoo() : _number( 0 )
{
this->_mutex = CreateMutex( NULL, FALSE, NULL );
}
~ConcurrentFoo()
{
CloseHandle( this->_mutex );
}
//並列的に実行するメソッド
//※並行度は高いが遅い
void AddFunc( int count )
{
for ( int i = 0; i < count; i++ ) {
WaitForSingleObject( this->_mutex, INFINITE );
++this->_number;
ReleaseMutex( this->_mutex );
}
}
ミューテックス・カーネルオブジェクトに関する部分を抜粋しました。このサンプルを見れば分かると思いますが、ミューテックス・カーネルオブジェクトもクリティカルセクション同様、オブジェクトの初期化・待機・解放・オブジェクトの削除の4つの関数を使用します。クリティカルセクションとの違いは、ミューテックス・カーネルオブジェクトは独自の構造体ではなく、普通のハンドルを使用している点です。その点さえ気をつければ、クリティカルセクションとほぼ同様に、ミューテックス・カーネルオブジェクトに関する関数を使用できます。ですから、分からないのはCreateMutex関数だけだと思います。
CreateMutex関数のパラメータは順に、セキュリティ属性・所有の有無を示すフラグ・名前の3つの引数を受け取ります。所有の有無とは、既にミューテックス・カーネルオブジェクトが誰かに所有されているのかを示します。通常はFALSEを指定し、ミューテックス・カーネルオブジェクトが保持するスレッドIDと再帰カウンタを0に初期化します。
ミューテックス・カーネルオブジェクトは再帰カウンタを持ち、カウンタの値を調べる事によりアクセスの状態を判断しています。ミューテックス・カーネルオブジェクトは、待機が成功するたびに再帰カウンタをインクリメントし、ReleaseMutex関数が呼び出されるごとに再帰カウンタをデクリメントします。これにより、排他的にアクセスをする事が可能となります。続く...