複数のスレッドはそれぞれが独立して動作するため、衝突したりデッドロックを引き起こす場合があります。
複数のスレッドから同じデータに同時にアクセスする場合は同期を行う必要があります。
スレッドを同期させるためにWindowsAPIには以下の機能が用意されています。
クリティカル セクションを使うと、一度に 1 つのスレッドだけがデータやリソースにアクセスできるようなります。
| 関数名 | 機能 |
|---|---|
| InitializeCriticalSection | クリティカルセクションオブジェクトを初期化します。 |
| DeleteCriticalSection | クリティカルセクションオブジェクトが使用しているすべてのリソースを解放します。 |
| EnterCriticalSection | クリティカルセクションオブジェクトの所有権が得られるまで待機します。 所有権が得られると制御が返ります。 |
| LeaveCriticalSection | クリティカルセクションオブジェクトの所有権を解放します。 |
青で表示されている行をコメントにすると同期を行いません。
#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;
}