LONG InterlockedExchangeAdd(LPLONG SrcVal, LONG AddVal);
Declare Function "InterlockedDecrement" Lib "kernel32" ( _ ByRef SrcVal As Long, _ ByVal AddVal As Long ) As Long
コンパイル結果の実行コードや実行環境によっては、複数のスレッドから参照される値に対して単純に加算を行うと不都合が起きる場合がある。このような場合に、InterlockedExchangeAdd関数を使用する。
この関数は、NTのみ使用可能。
引数は、以下の通り。
SrcVal | out | 加算を行う32bit値へのポインタ |
AddVal | in | 加算値 |
戻り値は、加算前の32bit値である。
実行環境がマルチプロセッサシステムならば、SrcValが指すメモリ領域は32bit境界に整列されていなければならない。
/* スレッド関数 * カウンタを100000000増やす */ DWORD WINAPI DoThread(LPDWORD pCnt) { int i; for(i=0; i<10000000; i++) { InterlockedExchangeAdd(pCnt, 10); } return(0); } /* メイン関数 * 上記スレッド関数を3個作成することにより、カウンタを300000000増やす */ int main(int argc, char **argv) { HANDLE hThread[3]; DWORD ThreadId; LPDWORD pCnt; int i; /* カウンタの初期化 */ pCnt = GlobalAlloc(GMEM_FIXED, sizeof(DWORD)); *pCnt = 0; /* スレッド作成 */ for(i=0; i<3; i++) { hThread[i] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)DoThread, pCnt, 0, &ThreadId); } /* 待機 */ WaitForMultipleObjects(3, hThread, TRUE, INFINITE); /* 実行結果表示 */ printf("Counter = %d\n", *pCnt); /* 後処理 */ for(i=0; i<3; i++) CloseHandle(hThread[i]); GlobalFree(pCnt); return(0); }