The InterlockedCompareExchange function performs an atomic comparison of the values of two memory locations and, if they are equal, stores a third value into the first memory location and returns the initial value of the first memory location.
LONG InterlockedCompareExchange(
[in, out] LONG volatile *Destination,
[in] LONG Exchange,
[in] LONG Comparand
);
| Parameter | Type | Description |
|---|---|---|
Destination |
LONG volatile * |
A pointer to the value to be replaced. |
Exchange |
LONG |
The value that is stored if the comparison is equal. |
Comparand |
LONG |
The value to compare against the value at Destination. |
The InterlockedCompareExchange function returns the initial value of the Destination parameter.
The InterlockedCompareExchange function provides a way to perform a compare-and-swap operation atomically. This is critical for preventing race conditions in multithreaded environments. If the value at Destination is equal to Comparand, the value of Exchange is written to the memory location pointed to by Destination. Otherwise, no operation is performed.
This function is part of the Windows API for low-level synchronization primitives. For higher-level synchronization constructs, consider using C++ Standard Library features like std::atomic.
The following C++ code snippet demonstrates how to use InterlockedCompareExchange to atomically increment a counter.
#include <windows.h>
#include <iostream>
#include <thread>
#include <vector>
volatile LONG sharedCounter = 0;
void incrementCounter() {
LONG oldValue;
LONG newValue;
do {
oldValue = sharedCounter;
newValue = oldValue + 1;
} while (InterlockedCompareExchange(&sharedCounter, newValue, oldValue) != oldValue);
}
int main() {
const int numThreads = 10;
const int incrementsPerThread = 10000;
std::vector<std::thread> threads;
for (int i = 0; i < numThreads; ++i) {
threads.emplace_back([&]() {
for (int j = 0; j < incrementsPerThread; ++j) {
incrementCounter();
}
});
}
for (auto& t : threads) {
t.join();
}
std::cout << "Final counter value: " << sharedCounter << std::endl; // Should be 100000
return 0;
}
This documentation is based on the Windows API reference.