fonctions intrinsèques de _InterlockedDecrement
Section spécifique à Microsoft
Fournit une prise en charge des intrinsèques du compilateur pour la fonction Win32 Kit de développement logiciel Windows InterlockedDecrement.
long _InterlockedDecrement(
long * lpAddend
);
long _InterlockedDecrement_acq(
long * lpAddend
);
long _InterlockedDecrement_rel(
long * lpAddend
);
long _InterlockedDecrement_nf(
long * lpAddend
);
short _InterlockedDecrement16(
short * lpAddend
);
short _InterlockedDecrement16_acq(
short * lpAddend
);
short _InterlockedDecrement16_rel(
short * lpAddend
);
short _InterlockedDecrement16_nf(
short * lpAddend
);
__int64 _InterlockedDecrement64(
__int64 * lpAddend
);
__int64 _InterlockedDecrement64_acq(
__int64 * lpAddend
);
__int64 _InterlockedDecrement64_rel(
__int64 * lpAddend
);
__int64 _InterlockedDecrement64_nf(
__int64 * lpAddend
);
Paramètres
- [in, out] lpAddend
Pointeur vers la variable à décrémenter.
Valeur de retour
La valeur de retour est la valeur décrémentée résultante.
Configuration requise
Intrinsèque |
Architecture |
---|---|
_InterlockedDecrement, _InterlockedDecrement16, _InterlockedDecrement64 |
x86, ARM, x64 |
_InterlockedDecrement_acq, _InterlockedDecrement_rel, _InterlockedDecrement_nf, _InterlockedDecrement16_acq, _InterlockedDecrement16_rel, _InterlockedDecrement16_nf, _InterlockedDecrement64_acq, _InterlockedDecrement64_rel, _InterlockedDecrement64_nf, |
ARM |
Fichier d'en-tête <intrin.h>
Notes
Il existe plusieurs variantes de _InterlockedDecrement qui varient selon les types de données qu'elles impliquent et l'utilisation d'une sémantique acquire ou release spécifique au processeur.
La fonction _InterlockedDecrement opère sur des valeurs entières de 32 bits, _InterlockedDecrement16 sur des valeurs entières de 16 bits et _InterlockedDecrement64 sur des valeurs entières de 64 bits.
Sur les plateformes ARM, utilisez les fonctions intrinsèques avec des suffixes _acq et _rel si vous devez acquérir et libérer des éléments de la sémantique, comme le début et la fin d'une section critique. Les fonctions intrinsèques avec un suffixe _nf (pour « no fence », « pas de délimitation ») n'agissent pas comme une barrière mémoire.
La variable vers laquelle pointe le paramètre lpAddend doit être alignée sur une limite de 32 bits. Dans le cas contraire, cette fonction échoue sur les systèmes x86 multiprocesseurs et les systèmes autres que x86. Pour plus d'informations, consultez align.
Ces routines sont disponibles seulement comme fonctions intrinsèques.
Exemple
// 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);
}