转载 2012年03月31日 14:31:21
Visual Studio 2010 - Visual C++

Microsoft Specific

Performs a 128-bit interlocked compare and exchange.

unsigned char _InterlockedCompareExchange128(
   __int64 volatile * Destination,
   __int64 ExchangeHigh,
   __int64 ExchangeLow,
   __int64 * ComparandResult
[in, out] Destination

Pointer to the destination, which is an array of two 64-bit integers considered as a 128-bit field. The destination data must be 16-byte aligned to avoid a general protection fault.

[in] ExchangeHigh

A 64-bit integer that may be exchanged with the high part of the destination.

[in] ExchangeLow

A 64-bit integer that may be exchanged with the low part of the destination.

[in, out] ComparandResult

Pointer to an array of two 64-bit integers (considered as a 128-bit field) to compare with the destination. On output, this is overwritten with the original value of the destination.

Return Value

1 if the 128-bit comparand equals the original value of the destination. ExchangeHigh and ExchangeLow overwrite the 128-bit destination.

0 if the comparand does not equal the original value of the destination. The value of the destination is unchanged and the value of the comparand is overwritten with the value of the destination.






Header file <intrin.h>


This intrinsic generates the cmpxchg16b instruction (with the lock prefix) to perform a 128-bit locked compare and exchange. Early versions of AMD 64-bit hardware do not support this instruction. To check for hardware support for the cmpxchg16b instruction, call the __cpuid intrinsic with InfoType=0x00000001 (standard function 1). Bit 13 of CPUInfo[2] (ECX) is 1 if the instruction is supported.


The value of ComparandResult is always overwritten. After the lock instruction, this intrinsic immediately copies the initial value of Destination to ComparandResult. For this reason, ComparandResult and Destination should point to separate memory locations to avoid unexpected behavior.

Although you can use _InterlockedCompareExchange128 for low-level thread synchronization, you do not need to synchronize over 128 bits if you can use smaller synchronization functions (such as the other _InterlockedCompareExchange intrinsics) instead. Use _InterlockedCompareExchange128 if you want atomic access to a 128-bit value in memory.

If you run code that uses this intrinsic on hardware that does not support the cmpxchg16b instruction, the results are unpredictable.

This routine is available only as an intrinsic.


This example uses _InterlockedCompareExchange128 to replace the high word of an array of two 64-bit integers with the sum of its high and low words and to increment the low word. The access to the BigInt.Int array is atomic, but this example uses a single thread and ignores the locking for simplicity.

// cmpxchg16b.c
// processor: x64
// compile with: /EHsc /O2
#include <stdio.h>
#include <intrin.h>

typedef struct _LARGE_INTEGER_128 {
    __int64 Int[2];

volatile LARGE_INTEGER_128 BigInt;

// This AtomicOp() function atomically performs:
//   BigInt.Int[1] += BigInt.Int[0]
//   BigInt.Int[0] += 1
void AtomicOp ()
    LARGE_INTEGER_128 Comparand;
    Comparand.Int[0] = BigInt.Int[0];
    Comparand.Int[1] = BigInt.Int[1];
    do {
        ; // nothing
    } while (_InterlockedCompareExchange128(BigInt.Int,
                                            Comparand.Int[0] + Comparand.Int[1],
                                            Comparand.Int[0] + 1,
                                            Comparand.Int) == 0);

// In a real application, several threads contend for the value
// of BigInt.
// Here we focus on the compare and exchange for simplicity.
int main(void)
   BigInt.Int[1] = 23;
   BigInt.Int[0] = 11;
   printf("BigInt.Int[1] = %d, BigInt.Int[0] = %d\n",
BigInt.Int[1] = 34, BigInt.Int[0] = 12
END Microsoft Specific

Copyright 2007 by Advanced Micro Devices, Inc. All rights reserved. Reproduced with permission from Advanced Micro Devices, Inc.


InterlockedCompareExchange 例程执行一个原子操作,用参数Comparand的值与参数Destination指针指向的值比较。Syntax:LONG InterlockedCo...
  • mofabang
  • mofabang
  • 2015年11月18日 11:18
  • 1229


所谓原子访问,指的是一个线程在访问某个资源的同时能够保证没有其他线程会在同一时刻访问同一资源。Interlocked系列函数提供了这样的操作。所有这些函数会以原子方式来操控一个值。 Interloc...
  • zhongguoren666
  • zhongguoren666
  • 2012年05月07日 16:46
  • 11343

InterlockedCompareExchange 用法

InterlockedAdd 用来解决对一个变量做加法时多线程同步问题。 比如:void AddSize(LONG lAdd){      InterlockedAdd (&g_lSize, lAdd...
  • wzsy
  • wzsy
  • 2011年06月03日 15:43
  • 7503

linux _InterlockedCompareExchange128的实现

#include namespace types { struct uint128_t { uint64_t lo; uint64_t hi; } __attr...
  • summerhust
  • summerhust
  • 2012年04月01日 17:55
  • 1945


个人网站 邮箱   LONG   InterlockedCompareExchange(     IN OUT ...
  • zhangliang1223
  • zhangliang1223
  • 2012年05月29日 20:26
  • 3379


本文供给Delphi一个基于原子操纵的无锁队列,简略单纯高效。实用于多线程大吞吐量操纵的队列。 科学是使人精力变得大胆的最好路子。可用于Android体系和32,64位Windows体系。 ...
  • rocklee
  • rocklee
  • 2015年09月29日 10:50
  • 1611


在大多数计算机上,增加变量操作不是一个原子操作,需要执行下列步骤: 1.       将实例变量中的值加载到寄存器中。 2.       增加或减少该值。 3.       在实例变量中存储该值。 ...
  • xgugu1210
  • xgugu1210
  • 2015年12月04日 16:23
  • 306


InterlockedCompareExchange128 Visual Studio 2010 - Visual C++ _InterlockedCompareExchange128 ...
  • summerhust
  • summerhust
  • 2012年03月31日 14:31
  • 1676


LONG InterlockedExchange( IN OUT PLONG Target, IN LONG Value );   Inter...
  • chenyujing1234
  • chenyujing1234
  • 2012年08月07日 17:08
  • 19104


所谓原子访问,指的是一个线程在访问某个资源的同时能够保证没有其他线程会在同一时刻访问同一资源。Interlocked系列函数提供了这样的操作。所有这些函数会以原子方式来操控一个值。 Interloc...
  • kingswb
  • kingswb
  • 2016年05月05日 21:26
  • 582