Win32API クリティカルセクションによるスレッドの排他制御
クリティカルセクションによるスレッドの同期制御
使用するAPI
CRITICAL_SECTION構造体は以下のように定義されていた(VisualStudio2005)
//////////////////////////////////////////////////////////// //WinNt.h typedef struct _RTL_CRITICAL_SECTION { PRTL_CRITICAL_SECTION_DEBUG DebugInfo; // // The following three fields control entering and exiting the critical // section for the resource // LONG LockCount; LONG RecursionCount; HANDLE OwningThread; // from the thread's ClientId->UniqueThread HANDLE LockSemaphore; ULONG_PTR SpinCount; // force size on 64-bit systems when packed } RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
///////////////////////////////////////////////// //WinBase.h typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; typedef PRTL_CRITICAL_SECTION PCRITICAL_SECTION; typedef PRTL_CRITICAL_SECTION LPCRITICAL_SECTION;
サンプルプログラムは、10スレッド起動し、それそれのスレッドがint型変数g_nCountをインクリメントする際に排他制御を行う。この排他制御により、g_nCountが正常に1ずつインクリメントされる。EnterCriticalSectionとLeaveCriticalSectionをコメントアウトすると、排他制御の効果がなくなることが分かる。
#include <windows.h> #include <process.h> int g_nCount; CRITICAL_SECTION cs; unsigned int WINAPI ThreadFunc(LPVOID arg) { int i; for (i = 0; i < 100; i++) { EnterCriticalSection(&cs); printf("%d\n", g_nCount++); LeaveCriticalSection(&cs); Sleep(50); } return 0; } int main() { HANDLE hThreads[10]; int nNumberOfThreads = sizeof(hThreads) / sizeof(hThreads[0]); unsigned int uiThreadId; int i; DWORD dwRet; InitializeCriticalSection(&cs); for (i = 0; i < nNumberOfThreads; i++) { hThreads[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, NULL, 0, &uiThreadId); if (hThreads[i] == NULL) { printf("_beginthreadex failed %d\n", i); } } dwRet = WaitForMultipleObjects( nNumberOfThreads, hThreads, TRUE, INFINITE); if (dwRet != WAIT_OBJECT_0) { puts("WaitForMultipleOnject Error"); } for (i = 0; i < nNumberOfThreads; i++) { CloseHandle(hThreads[i]); } DeleteCriticalSection(&cs); return 0; }