2012年(158)
分类: C/C++
2012-11-19 13:10:35
Intel
CPU相关指令:
LOCK
这是一个指令前缀,在所对应的指令操作期间使此指令的目标操作数指定的存储区域锁定,以得到保护。
XADD
先交换两个操作数的值,再进行算术加法操作。多处理器安全,在80486及以上CPU中支持。
CMPXCHG
比较交换指令,第一操作数先和AL/AX/EAX比较,如果相等ZF置1,第二操作数赋给第一操作数,否则ZF清0,第一操作数赋给AL/AX/EAX。
多处理器安全,在80486及以上CPU中支持。
CMPXCHG8B
同上,64位比较交换指令,第二操作数隐含为EDX:EAX,比较EDX:EAX与64位的目标,如果相等则ECX:EBX送往目标且ZF置1,否则目标送EDX:EAX且ZF清0。
windows互锁API列表:
InterlockedCompareExchange/InterlockedCompareExchange64
InterlockedCompareExchangeAcquire/InterlockedCompareExchangeAcquire64
InterlockedCompareExchangePointer
InterlockedCompareExchangeRelease/InterlockedCompareExchangeRelease64
InterlockedDecrement/InterlockedDecrement64
InterlockedDecrementAcquire
InterlockedDecrementRelease
InterlockedExchange/InterlockedExchange64
InterlockedExchangeAcquire64
InterlockedExchangeAdd/InterlockedExchangeAdd64
InterlockedExchangePointer
InterlockedIncrement/InterlockedIncrement64
InterlockedIncrementAcquire
InterlockedIncrementRelease
看一个简单的函数,它的作用是将lpAddend加1,并返回之。
LONG InterlockedIncrement( LPLONG lpAddend
)
{
MOV ecx, lpAddend
MOV eax, 1
LOCK XADD dword ptr [ecx], eax
INC eax
RET
4
}
看一个复杂的函数,它的作用是将lValue赋值给*plTarget,并返回*plTarget的原先值。
LONG
InterlockedExchange( LPLONG plTarget, LONG lValue )
{
MOV
ecx, plTarget
MOV edx, lValue
MOV eax, dword
ptr [ecx]
L: LOCK CMPXCHG dword ptr [ecx], edx
JNE
L
RET
8
}
看,不得不动用了一个循环指令。类似的还有InterlockedCompareExchange(pdestination,exchage,comperand)函数,如果Destination等于Comperand,将Exchange赋值给Destination,否则什么也不干,返回值为Destination的原先值。
循环技巧是很有用的,Jeffrey Richter给出了一个功能代码,如果值大于0,则加1,代码如下:
do {
LONG
lStartValue = *plTarget;
LONG lNewValue = lStartValue + ((lStartValue
> 0) ? 1 : 0);
} while(
InterlockedCompareExchange(plTarget,lNewValue,lStartValue) != lStartValue );
一个未知的问题是,为什么在有的操作系统中没看到LOCK。未来的研究是线程/进程锁。
网友评论2012-11-19 13:16:10
Tongshou
星星:
您好!这里再请教2个问题:
1) VC++: Interlockedxxx族函数,在高版本中增加一个修饰符 volatile,比如:
LONG __cdecl InterlockedIncrement(
__inout LONG volatile *Addend
);
而在VC6低版本中没有volatile,是否意味低版本有安全问题?
2)对静态数据使用volatile修饰方便, 比如:
LONG volatile count=0;
...
InterlockedIncrement( &count);
对于动态的数据,是否可以用volatile修饰,达到安全保障? 如:
LONG volati
网友评论2012-11-19 13:15:38
test
抱歉!我并不同意您的解释,特别是您的举例不能用来解释这些问题。
一、 InterlockedExchange 函数以原子“总是”交换数据
InterlockedCompareExchange 函数以原子“有可能”交换数据
因此在MS的代码中,后者与前者的差别主要就是没有了条件跳转。
二、 我认为用LOCK XCHG是完全可以用来简化InterlockedExchange的实现函数的。
事实在我实际编程中,也都是用LOCK XCHG来以原子的方式交换数据。
因为InterlockedExchange只是交换,不存在条件交换。条件交换才用LOCK CMPXCHG,
MS的InterlockedExchange中的循环我认为是无意义的。^_^
---------------------------------------------------------------------------
LONG In