《Windows核心编程系列》谈谈用户模式下的线程同步
作者:网络转载 发布时间:[ 2012/10/17 10:55:12 ] 推荐标签:
前面的代码可以改成下面的代码:
Long a;
DWORD WINAPI ThreadFunc2(PVOID pvParam)
{
InterlockedExchangeAdd(&a,1);
Return 0;
}
改成上述代码后,对a的递增都是以原子方式进行。也可以保证a的终结果为2。如果只想以原子方式给一个值加1的话,可以使用InterlockedIncrement函数。
这些Interlock系列函数的工作机制取决于代码运行的cpu平台。如果是x86平台,那么Interlock函数会在总线上维持一个硬件信号,这个信号会阻止其他cpu访问同一个内存地址。
我们并不需要理解Interlock函数是如何工作的。无论编译器如何生成代码,无论机器上装了多少cpu,这些函数都能保证对值的修改是以原子方式进行的。
Interlock系列函数执行速度极快。通常只需要几个cpu周期,而且不需要在用户模式和内核模式进行切换。
使用这些函数也可以做减法,只要传入负值即可。
如果需要以原子方式执行变量交换可以调用:
LONG InterlockedExchange(
PLONG volatile plTarget,
LONG lValue);
LONGLONG InterlockedExchange64(
PLONGLONG volatile plTarget,
LONGLONG lValue);
PVOID InterlockedPointer(
PVOID *volatile ppvTarget,
PVOID pvValue);
InterloackedExchange和InterlockedExchangePointer会把第一个参数所指向的内存地址的当前值以原子方式替换为第二个参数指定的值
对于32位应用程序来说,它们都是替换的32位的值。而对于64位的应用程序InterlockedExchangePointer是替换的64位的值。因为此时指针也是64位的。
这两个函数都返回原来的值,在实现旋转锁时,InterlockedExchange函数非常有用。
Bool use=false;
Void func()
{
While(InterlockedExchange(&use,true)==true)
Sleep(0);
//........
InterlockedExchange(&use,false);
}
While循环不停的执行,把use的值设为true并检查原来的值是否为true。如果原来的值为false,则说明资源尚未被使用。于是将其设为使用中。如果原来的值是true则表明有其他线程正在使用该资源,调用sleep放弃该时间片的调度。

sales@spasvo.com