Win32API 複数スレッド間で同期的に整数をインクリメント、デクリメントする InterlockedIncrement, InterlockedDecrement
複数スレッド間で1つの共有オブジェクトにアクセスする際には、同期処理を行う必要がある。複数スレッド間で共有する整数値を同期的にインクリメント、デクリメントを行うには、InterlockedIncrement関数、InterlockedDecrement関数を用いる。
InterlockedIncrementのプロトタイプ
LONG InterlockedIncrement( LPLONG lpAddend // インクリメントするべき変数 );
InterlockedDecrementのプロトタイプ
LONG InterlockedDecrement( LPLONG lpAddend // デクリメントするべき変数 );
複数のインクリメント用スレッドとデクリメント用スレッドが1つの整数型グローバル変数 g_dwCount にアクセスし、インクリメントとデクリメントを同じ回数だけ行う。スレッドの同期処理を行っているため、最終的には整数型グローバル変数 g_dwCount は初期値であるゼロに戻っている。
#include <windows.h> #include <process.h> #include <stdio.h> DWORD g_dwCount = 0; unsigned int WINAPI IncrementThread(void *arg) { for (int i = 0; i < 100; i++) { InterlockedIncrement((volatile LONG*)&g_dwCount); printf("Increment: g_dwCount = %u\n", g_dwCount); Sleep(rand() % 10); } return 0; } unsigned int WINAPI DecrementThread(void *arg) { for (int i = 0; i < 100; i++) { InterlockedDecrement((volatile LONG*)&g_dwCount); printf("Decrement: g_dwCount = %u\n", g_dwCount); Sleep(rand() % 20); } return 0; } int main() { HANDLE hThreads[100]; size_t nThreads = sizeof(hThreads) / sizeof(hThreads[0]); unsigned int uiThreadId; for (size_t i = 0; i < nThreads; i++) { hThreads[i] = (HANDLE)_beginthreadex(NULL, 0, i % 2 == 0 ? IncrementThread : DecrementThread, NULL, 0, &uiThreadId); } for (size_t i = 0; i < nThreads; i++) { WaitForSingleObject(hThreads[i], INFINITE); } for (size_t i = 0; i < nThreads; i++) { CloseHandle(hThreads[i]); } printf("Result of g_dwCount = %u\n", g_dwCount); return 0; }
参考
http://msdn.microsoft.com/ja-jp/library/cc429236.aspx
http://msdn.microsoft.com/ja-jp/library/cc429229.aspx