InterlockedExchangeAdd 共有されている変数の加算

Cの宣言:

LONG InterlockedExchangeAdd(LPLONG SrcVal, LONG AddVal);

VBの宣言:

Declare Function "InterlockedDecrement" Lib "kernel32" ( _
	ByRef SrcVal As Long, _
	ByVal AddVal As Long
) As Long

説明:

複数のスレッドから参照される32bit値に対して加算を行う。プロセス間での使用も可能である。

コンパイル結果の実行コードや実行環境によっては、複数のスレッドから参照される値に対して単純に加算を行うと不都合が起きる場合がある。このような場合に、InterlockedExchangeAdd関数を使用する。

この関数は、NTのみ使用可能。

引数は、以下の通り。
SrcVal out 加算を行う32bit値へのポインタ
AddVal in 加算値

戻り値は、加算前の32bit値である。

実行環境がマルチプロセッサシステムならば、SrcValが指すメモリ領域は32bit境界に整列されていなければならない。

Cのサンプル:

/* スレッド関数
 * カウンタを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);
}
(original text:1998/12/25 更新)

本ドキュメントの内容は保証しません。本ドキュメントによって生じた結果について、一切の責任を負いません。