Skip to content

多线程中的互锁操作

多线程中的互锁操作 published on 多线程中的互锁操作有116条评论

        在Win32平台下,为了让同一进程的多个线程访问某一相同变量时不冲突,我们可以使用互锁操作。它提供了一个简便实用的方式,它并不取代传统的同步对象,如临界区、信号量、互斥等,它是一个更加快速且有效的方式。

        互锁操作是一种基于硬件的同步技术,而不是基于操作系统本身的机制,它拥有普通同步对象不可比拟的性能。它可以以原子方式更新一个四字节或八字节的变量,例如 int、longlong、ptr 等。互锁的实现是基于硬件的,在某些情况下它可能转换为一个单一的CPU处理器指令,而任意一条CPU指令都可以看作是一个原子操作。

        什么是原子操作呢?一个原子操作是不可再分割的。简单来说假如在一个多线程程序中,对某个全局变量执行一个加法操作,在这个加法操作完成之前,不存在也不允许另一个线程来读取这个全局变量,那么这个加法操作就被称为一个原子写操作。但事实上并非如此简单,以Win32系统为例子,一个句普通的C/C++加法语句都有很大可能不是一个原子操作。在线程执行过程中,真正可以被称原子操作的只能是单条CPU指令,因为操作系统发生线程切换时不可能在某条指令的执行过程中,只可能在两条指令之间。如果能熟练掌握和运用互锁操作绝对有利于增加程序的健壮性和降低编写多线程程序的难度。

                相比传统的同步操作而言,互锁操作使用更简单而且效率更高,它是一种有针对性的、轻量级的同步操作。首先互锁操作直接支持一个或多个CPU(但不是跨进程),这是在硬件上完成的。通过各种编译器的支持,互锁操作直接提供了函数的形式的调用(WIN32下,见文章尾处的表)。这是一种非常友好的方式,它使C/C++程序员无需熟悉CPU指令或操作系统底层就可以直接使用它。当在多线程程序中,如果不使用同步操作来保证某一变量的在同一时间段(这个时间段可能非常短)的唯一性的话,那么非常容易引发竞争条件。竞争条件是指,两个或两个以上的线程在访问同一变量时执行顺序不可被预期,线程的控制权被强制转移了,这个不可预知性便照成了所谓的竞争条件。

        使用互锁操作,某一线程等待的状态将不复存在。如果在一个多线程程序中使用临界区或互斥对象锁定一个操作,那么将摆脱不了一个线程可能等待另一个线程的解锁的状况。而互锁操作则不会,它将立即完成。互锁的这种特性是多线程无锁编程的基础,多线程无锁编程是一种模式,它是在多线程下情况下不使用传统同步对象来控制数据同步的基础。互锁操作不会像互斥对象那样,在使用时存在从用户态到核心态的转换,这是互锁的一大优势。对大多数平台而言,从用户态转换到核心态的转换会消耗较多的CPU资源,简单说就是会使你的函数变慢!

        当然互锁操作并不是万能的,比如在多线程程序中操作某个对象的一批成员变量时,你无法避免使用传统的同步方法。它的另一个限制其实在本文的开头已经提到,它无法跨进程起作用,如果你要同步两个不同进程中的变量,仍然需要使用互斥对象或其他同步对象。

        这里想说明一下的就是和互锁相关的代码编写方面的一些建议:

  • 绝对不要将互锁操作与传统同步对象混用。
  • 绝对不要在同一volatile变量上混合使用多种互锁操作。
  • 如果你的程序正在执行与内存写入相关的互锁操作,请在互锁调用之前使用内存栅栏。
  • 如果你的程序正在执行与内存读取相关的互锁操作,请在互锁调用之后使用内存栅栏。

        这里我只给出了建议,未给出原理,因为涉及的东西实在太多太多……,希望以后有时间写一篇或几篇专门的文章来做补充说明。

        注意,在某些互锁函数中,MSDN备注栏有这样一句话:

This function is supported only on Itanium Processor Family (IPF).

        这就是说,这个互锁函数只支持安腾系列的CPU,其他架构的CPU是无法使用的,所以在编写代码的时候一定要预先确定CPU架构。

        我们来看看当前Windows平台下支持的一些互锁操作(下表来至MSDN): 

Interlocked function Description
InterlockedAdd Performs an atomic addition operation on the specified LONG values.
InterlockedAdd64 Performs an atomic addition operation on the specified LONGLONG values.
InterlockedAddAcquire Performs an atomic addition operation on the specified LONG values. The operation is performed with acquire memory access semantics.
InterlockedAddAcquire64 Performs an atomic addition operation on the specified LONGLONG values. The operation is performed with acquire memory access semantics.
InterlockedAddRelease Performs an atomic addition operation on the specified LONG values. The operation is performed with release memory access semantics.
InterlockedAddRelease64 Performs an atomic addition operation on the specified LONGLONG values. The operation is performed with release memory access semantics.
InterlockedAnd Performs an atomic AND operation on the specified LONG values.
InterlockedAndAcquire Performs an atomic AND operation on the specified LONG values. The operation is performed with acquire memory access semantics.
InterlockedAndRelease Performs an atomic AND operation on the specified LONG values. The operation is performed with release memory access semantics.
InterlockedAnd8 Performs an atomic AND operation on the specified char values.
InterlockedAnd8Acquire Performs an atomic AND operation on the specified char values. The operation is performed with acquire memory access semantics.
InterlockedAnd8Release Performs an atomic AND operation on the specified char values. The operation is performed with release memory access semantics.
InterlockedAnd16 Performs an atomic AND operation on the specified SHORT values.
InterlockedAnd16Acquire Performs an atomic AND operation on the specified SHORT values. The operation is performed with acquire memory access semantics.
InterlockedAnd16Release Performs an atomic AND operation on the specified SHORT values. The operation is performed with release memory access semantics.
InterlockedAnd64 Performs an atomic AND operation on the specified LONGLONG values.
InterlockedAnd64Acquire Performs an atomic AND operation on the specified LONGLONG values. The operation is performed with acquire memory access semantics.
InterlockedAnd64Release Performs an atomic AND operation on the specified LONGLONG values. The operation is performed with release memory access semantics.
InterlockedBitTestAndReset Tests the specified bit of the specified LONG value and sets it to 0.
InterlockedBitTestAndReset64 Tests the specified bit of the specified LONG64 value and sets it to 0.
InterlockedBitTestAndSet Tests the specified bit of the specified LONG value and sets it to 1.
InterlockedBitTestAndSet64 Tests the specified bit of the specified LONG64 value and sets it to 1.
InterlockedCompare64Exchange128 Performs an atomic compare-and-exchange operation on the specified values. The function compares the specified 64-bit values and exchanges with the specified 128-bit value based on the outcome of the comparison.
InterlockedCompare64ExchangeAcquire128 Performs an atomic compare-and-exchange operation on the specified values. The function compares the specified 64-bit values and exchanges with the specified 128-bit value based on the outcome of the comparison. The operation is performed with acquire memory access semantics.
InterlockedCompare64ExchangeRelease128 Performs an atomic compare-and-exchange operation on the specified values. The function compares the specified 64-bit values and exchanges with the specified 128-bit value based on the outcome of the comparison. The operation is performed with release memory access semantics.
InterlockedCompareExchange Performs an atomic compare-and-exchange operation on the specified values. The function compares two specified 32-bit values and exchanges with another 32-bit value based on the outcome of the comparison.
InterlockedCompareExchange64 Performs an atomic compare-and-exchange operation on the specified values. The function compares two specified 64-bit values and exchanges with another 64-bit value based on the outcome of the comparison.
InterlockedCompareExchangeAcquire Performs an atomic compare-and-exchange operation on the specified values. The function compares two specified 32-bit values and exchanges with another 32-bit value based on the outcome of the comparison. The operation is performed with acquire memory access semantics.
InterlockedCompareExchangeAcquire64 Performs an atomic compare-and-exchange operation on the specified values. The function compares two specified 64-bit values and exchanges with another 64-bit value based on the outcome of the comparison. The exchange is performed with acquire memory access semantics.
InterlockedCompareExchangePointer Performs an atomic compare-and-exchange operation on the specified pointer values. The function compares two specified pointer values and exchanges with another pointer value based on the outcome of the comparison.
InterlockedCompareExchangePointerAcquire Performs an atomic compare-and-exchange operation on the specified pointer values. The function compares two specified pointer values and exchanges with another pointer value based on the outcome of the comparison. The operation is performed with acquire memory access semantics.
InterlockedCompareExchangePointerRelease Performs an atomic compare-and-exchange operation on the specified pointer values. The function compares two specified pointer values and exchanges with another pointer value based on the outcome of the comparison. The operation is performed with release memory access semantics.
InterlockedCompareExchangeRelease Performs an atomic compare-and-exchange operation on the specified values. The function compares two specified 32-bit values and exchanges with another 32-bit value based on the outcome of the comparison. The exchange is performed with release memory access semantics.
InterlockedCompareExchangeRelease64 Performs an atomic compare-and-exchange operation on the specified values. The function compares two specified 64-bit values and exchanges with another 64-bit value based on the outcome of the comparison. The exchange is performed with release memory access semantics.
InterlockedDecrement Decrements (decreases by one) the value of the specified 32-bit variable as an atomic operation.
InterlockedDecrement64 Decrements (decreases by one) the value of the specified 64-bit variable as an atomic operation.
InterlockedDecrementAcquire Decrements (decreases by one) the value of the specified 32-bit variable as an atomic operation. The operation is performed with acquire memory access semantics.
InterlockedDecrementAcquire64 Decrements (decreases by one) the value of the specified 64-bit variable as an atomic operation. The operation is performed with acquire memory access semantics.
InterlockedDecrementRelease Decrements (decreases by one) the value of the specified 32-bit variable as an atomic operation. The operation is performed with release memory access semantics.
InterlockedDecrementRelease64 Decrements (decreases by one) the value of the specified 64-bit variable as an atomic operation. The operation is performed with release memory access semantics.
InterlockedExchange Sets a 32-bit variable to the specified value as an atomic operation.
InterlockedExchange64 Sets a 64-bit variable to the specified value as an atomic operation.
InterlockedExchangeAcquire Sets a 32-bit variable to the specified value as an atomic operation. The operation is performed with acquire memory access semantics.
InterlockedExchangeAcquire64 Sets a 32-bit variable to the specified value as an atomic operation. The operation is performed with acquire memory access semantics.
InterlockedExchangeAdd Performs an atomic addition of two 32-bit values.
InterlockedExchangeAdd64 Performs an atomic addition of two 64-bit values.
InterlockedExchangeAddAcquire Performs an atomic addition of two 32-bit values. The operation is performed with acquire memory access semantics.
InterlockedExchangeAddAcquire64 Performs an atomic addition of two 64-bit values. The operation is performed with acquire memory access semantics.
InterlockedExchangeAddRelease Performs an atomic addition of two 32-bit values. The operation is performed with release memory access semantics.
InterlockedExchangeAddRelease64 Performs an atomic addition of two 64-bit values. The operation is performed with release memory access semantics.
InterlockedExchangePointer Atomically exchanges a pair of pointer values.
InterlockedExchangePointerAcquire Atomically exchanges a pair of pointer values. The operation is performed with acquire memory access semantics.
InterlockedIncrement Increments (increases by one) the value of the specified 32-bit variable as an atomic operation.
InterlockedIncrement64 Increments (increases by one) the value of the specified 64-bit variable as an atomic operation.
InterlockedIncrementAcquire Increments (increases by one) the value of the specified 32-bit variable as an atomic operation. The operation is performed using acquire memory access semantics.
InterlockedIncrementAcquire64 Increments (increases by one) the value of the specified 64-bit variable as an atomic operation. The operation is performed using acquire memory access semantics.
InterlockedIncrementRelease Increments (increases by one) the value of the specified 32-bit variable as an atomic operation. The operation is performed using release memory access semantics.
InterlockedIncrementRelease64 Increments (increases by one) the value of the specified 64-bit variable as an atomic operation. The operation is performed using release memory access semantics.
InterlockedOr Performs an atomic OR operation on the specified LONG values.
InterlockedOrAcquire Performs an atomic OR operation on the specified LONG values. The operation is performed with acquire memory access semantics.
InterlockedOrRelease Performs an atomic OR operation on the specified LONG values. The operation is performed with release memory access semantics.
InterlockedOr8 Performs an atomic OR operation on the specified char values.
InterlockedOr8Acquire Performs an atomic OR operation on the specified char values. The operation is performed with acquire memory access semantics.
InterlockedOr8Release Performs an atomic OR operation on the specified char values. The operation is performed with release memory access semantics.
InterlockedOr16 Performs an atomic OR operation on the specified SHORT values.
InterlockedOr16Acquire Performs an atomic OR operation on the specified SHORT values. The operation is performed with acquire memory access semantics.
InterlockedOr16Release Performs an atomic OR operation on the specified SHORT values. The operation is performed with release memory access semantics.
InterlockedOr64 Performs an atomic OR operation on the specified LONGLONG values.
InterlockedOr64Acquire Performs an atomic OR operation on the specified LONGLONG values. The operation is performed with acquire memory access semantics.
InterlockedOr64Release Performs an atomic OR operation on the specified LONGLONG values. The operation is performed with release memory access semantics.
InterlockedXor Performs an atomic XOR operation on the specified LONG values.
InterlockedXorAcquire Performs an atomic XOR operation on the specified LONG values. The operation is performed with acquire memory access semantics.
InterlockedXorRelease Performs an atomic XOR operation on the specified LONG values. The operation is performed with release memory access semantics.
InterlockedXor8 Performs an atomic XOR operation on the specified char values.
InterlockedXor8Acquire Performs an atomic XOR operation on the specified char values. The operation is performed with acquire memory access semantics.
InterlockedXor8Release Performs an atomic XOR operation on the specified char values. The operation is performed with release memory access semantics.
InterlockedXor16 Performs an atomic XOR operation on the specified SHORT values.
InterlockedXor16Acquire Performs an atomic XOR operation on the specified SHORT values. The operation is performed with acquire memory access semantics.
InterlockedXor16Release Performs an atomic XOR operation on the specified SHORT values. The operation is performed with release memory access semantics.
InterlockedXor64 Performs an atomic XOR operation on the specified LONGLONG values.
InterlockedXor64Acquire Performs an atomic XOR operation on the specified LONGLONG values. The operation is performed with acquire memory access semantics.
InterlockedXor64Release Performs an atomic XOR operation on the specified LONGLONG values. The operation is performed with release memory access semantics.
原创文章,转载请注明: 转载自游戏无界·达秀的黑暗空间

本文链接地址: 多线程中的互锁操作

本站作品除特殊申明外均为原创,采用知识共享署名-非商业性使用-禁止演绎 3.0 Unported许可协议进行许可。如果需转载请保持文章完整性和标明原文出处,禁止商业用途。

  1. Pingback: Phillip

  2. Pingback: Armando

  3. Pingback: brett

  4. Pingback: fred

  5. Pingback: herbert

  6. Pingback: Lee