クリティカルセクションを使用したスレッドの同期


複数のスレッドはそれぞれが独立して動作するため、衝突したりデッドロックを引き起こす場合があります。
複数のスレッドから同じデータに同時にアクセスする場合は同期を行う必要があります。
スレッドを同期させるためにWindowsAPIには以下の機能が用意されています。

クリティカル セクションを使うと、一度に 1 つのスレッドだけがデータやリソースにアクセスできるようなります。

関数名 機能
InitializeCriticalSection クリティカルセクションオブジェクトを初期化します。
DeleteCriticalSection クリティカルセクションオブジェクトが使用しているすべてのリソースを解放します。
EnterCriticalSection クリティカルセクションオブジェクトの所有権が得られるまで待機します。
所有権が得られると制御が返ります。
LeaveCriticalSection クリティカルセクションオブジェクトの所有権を解放します。


Sample code

青で表示されている行をコメントにすると同期を行いません。


#include <windows.h>
#include <tchar.h>
#include <process.h>
#include <stdio.h>

unsigned int __stdcall MyThread(void *);

CRITICAL_SECTION cs;
volatile unsigned int count = 0;

unsigned int __stdcall MyThread(void *)
{
    int x;
    
    for(int i = 0; i < 100; i++) {
        EnterCriticalSection(&cs);
        x = count;
        Sleep(10);
        x++;
        count = x;
        _tprintf(TEXT("count : %d\r\n"), count);
        LeaveCriticalSection(&cs);
    }
    return 0;
}

int _tmain()
{
    InitializeCriticalSection(&cs);
    
    //3つのスレッドを生成します
    HANDLE hThread[3];
    for(int i = 0; i < 3; i++) {
        hThread[i] = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, MyThread, NULL, 0, NULL));
    }
    WaitForMultipleObjects(3, hThread, TRUE, INFINITE);
    
    for(int i = 0; i < 3; i++) {
        CloseHandle(hThread[i]);
    }
    DeleteCriticalSection(&cs);
    
    return 0;
}

一覧メニューへ