_InterlockedDecrement
内部函数
为 Win32 Windows SDK InterlockedDecrement 函数提供编译器内部支持。 _InterlockedDecrement
内部函数是 Microsoft 特定函数。
语法
long _InterlockedDecrement(
long volatile * lpAddend
);
long _InterlockedDecrement_acq(
long volatile * lpAddend
);
long _InterlockedDecrement_rel(
long volatile * lpAddend
);
long _InterlockedDecrement_nf(
long volatile * lpAddend
);
short _InterlockedDecrement16(
short volatile * lpAddend
);
short _InterlockedDecrement16_acq(
short volatile * lpAddend
);
short _InterlockedDecrement16_rel(
short volatile * lpAddend
);
short _InterlockedDecrement16_nf(
short volatile * lpAddend
);
__int64 _InterlockedDecrement64(
__int64 volatile * lpAddend
);
__int64 _InterlockedDecrement64_acq(
__int64 volatile * lpAddend
);
__int64 _InterlockedDecrement64_rel(
__int64 volatile * lpAddend
);
__int64 _InterlockedDecrement64_nf(
__int64 volatile * lpAddend
);
参数
lpAddend
[in, out] 指向要递减的变量的易失指针。
返回值
返回值是生成的递减值。
要求
Intrinsic | 体系结构 |
---|---|
%> | x86、ARM、x64、ARM64 |
_InterlockedDecrement64 |
ARM、x64、ARM64 |
ARM、ARM64 |
头文件<intrin.h>
注解
_InterlockedDecrement
存在几种变体,这些变体根据其涉及的数据类型和是否使用特定于处理器获取或发布语义而有所不同。
当 _InterlockedDecrement
函数对 32 位整数值操作时,_InterlockedDecrement16
对 16 位整数值操作且 _InterlockedDecrement64
可以对 64 位整数值操作。
ARM 平台上,如果需要(例如在临界区的起点和终点)获取和发布语义,可以使用带 _acq
和 _rel
后缀的函数。 带 _nf
(“no fence”)后缀的内部函数不充当内存屏障。
由 lpAddend
参数指向的变量必须与 32 位边界对齐;否则,此函数在多处理器 x86 系统和任何非 x86 系统上将失效。 有关详细信息,请参阅 align。
这些例程只能用作内部函数。
示例
// compiler_intrinsics_interlocked.cpp
// compile with: /Oi
#define _CRT_RAND_S
#include <cstdlib>
#include <cstdio>
#include <process.h>
#include <windows.h>
// To declare an interlocked function for use as an intrinsic,
// include intrin.h and put the function in a #pragma intrinsic
// statement.
#include <intrin.h>
#pragma intrinsic (_InterlockedIncrement)
// Data to protect with the interlocked functions.
volatile LONG data = 1;
void __cdecl SimpleThread(void* pParam);
const int THREAD_COUNT = 6;
int main() {
DWORD num;
HANDLE threads[THREAD_COUNT];
int args[THREAD_COUNT];
int i;
for (i = 0; i < THREAD_COUNT; i++) {
args[i] = i + 1;
threads[i] = reinterpret_cast<HANDLE>(_beginthread(SimpleThread, 0,
args + i));
if (threads[i] == reinterpret_cast<HANDLE>(-1))
// error creating threads
break;
}
WaitForMultipleObjects(i, threads, true, INFINITE);
}
// Code for our simple thread
void __cdecl SimpleThread(void* pParam) {
int threadNum = *((int*)pParam);
int counter;
unsigned int randomValue;
unsigned int time;
errno_t err = rand_s(&randomValue);
if (err == 0) {
time = (unsigned int) ((double) randomValue / (double) UINT_MAX * 500);
while (data < 100) {
if (data < 100) {
_InterlockedIncrement(&data);
printf_s("Thread %d: %d\n", threadNum, data);
}
Sleep(time); // wait up to half of a second
}
}
printf_s("Thread %d complete: %d\n", threadNum, data);
}