プログラミングメモ →目次

ミューテックスにより排他制御(VC++)

データの整合性を保つために、複数のスレッドが同時に同じデータを処理してはいけない場合があります。普段は、排他制御と言います。VC++では、排他制御の手段が幾つかがありますが、ミューテックスは方法の一つで、下記の3関数で、排他制御が実現できます。CreateMutex()で作成したミューテックスオブジェクトが、一つのスレッドにWaitForSingleObject()待機関数で所有権を取得したら、ReleaseMutex()関数で放棄処理するまで、他のスレッドの中でWaitForSingleObject()待機関数でミューテックの所有権を取得できないから、排他的なデータ処理をWaitForSingleObject()関数とReleaseMutex()関数の間に入れれば、排他制御ができるのです。

WINBASEAPI HANDLE WINAPI CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, 
                                     BOOL bInitialOwner, LPCSTR lpName);
WINBASEAPI DWORD WINAPI WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
WINBASEAPI BOOL WINAPI ReleaseMutex(HANDLE hMutex);

例:二つのスレッドの排他的な処理。

HANDLE g_mutexTest = NULL;

void CreateMutexTest()	//ミューテックスを作成、二つのスレッドを起動する
{
    ... ...
    g_mutexTest = CreateMutex( 0, FALSE, NULL);
    hThread1 = CreateThread(NULL, 0, ThreadFunc1, NULL, 0, &ThreadId);
    hThread2 = CreateThread(NULL, 0, ThreadFunc2, NULL, 0, &ThreadId);
    ... ...
}

DWORD WINAPI ThreadFunc1(LPVOID lpParam)         //スレッドの1
{
    ... ...
    WaitForSingleObject(g_mutexTest, INFINITE);  //所有権取得
    //排他的な処理
    ReleaseMutex(g_mutexTest);                   //所有権放棄
    ... ...
}

DWORD WINAPI ThreadFunc2(LPVOID lpParam)         //スレッドの2
{
    ... ...
    WaitForSingleObject(g_mutexTest, INFINITE);  //所有権取得
    //排他的な処理
    ReleaseMutex(g_mutexTest);                   //所有権放棄
    ... ...
}

void CloseMutex()
{
    ... ...
    if (g_mutexTest)
    {
        CloseHandle(g_mutexTest);
        g_mutexTest = NULL;
    }
    ... ...
}