《Windows核心编程》学习笔记(8)– 用户模式下的线程同步
原子访问:Interlocked系列函数所谓原子访问,指的是一个线程在访问某个资源的同时能够保证没有其他线程会在同一时刻访问同一资源。
LONG InterlockedExchangeAdd(
LONG volatile* Addend,
LONG Value
);
LONGLONG InterlockedExchangeAdd64(
LONGLONG volatile* Addend,
LONGLONG Value
);
上面两个函数:
参数Addend 为要递增或者递减的变量的地址
参数Value
为增量值,可以为负数,表示前一个变量参数递减。
LONG InterlockedExchange(
LONG volatile* Target,
LONG Value
);
LONGLONG InterlockedExchange64(
LONGLONG volatile* Target,
LONGLONG Value
);
PVOID InterlockedExchangePointer(
PVOID volatile* Target,
PVOID Value
);
上面三个函数会把第一个参数指向的内存地址的当前值,以原子的方式替换为第二个参数指定的值。
LONG InterlockedCompareExchange(
LONG volatile* Destination,
LONG Exchange,
LONG Comparand
);
PVOID InterlockedCompareExchangePointer(
PVOID volatile* Destination,
PVOID Exchange,
PVOID Comparand
);
上面这两个函数以原子的方式执行一个测试和设置操作。
函数会将参数Destination
指向的当前值与参数Comparand
的值进行比较。如果两个值相同,那么函数会将 *Destination 修改为Exchange 参数的值。否则,*Destination的值保持不变。函数会返回
*Destination 原来的值。
除了可以对整数或者布尔值进行这些原子操作外,我们还可以使用一系列的其他函数来对一种被称为Interlocked单项链表的栈进行操作。
InitializeSListHead 创建一个空栈
InterlockedPushEntrySList
在栈顶添加一个元素
InterlockedPopEntrySList
移除位于栈顶的元素并将它返回
InterlockedFlushSList
清空栈
QueryDepthSList 返回栈中元素的数量
关键段
关键段是一小段代码,它在执行之前需要独占对一些共享资源的访问权。这种方式可以让多行代码以“原子方式”来对资源进行控制。当然,系统仍然可以暂停当前线程去调度其他线程。但是,在当前线程离开关键段之前,系统是不会去调度任何想要访问同一资源的其他线程。
代码如下:
#include
#include
const int COUNT = 10;
int g_nSum = 0;
//定义CRITICAL_SECTION 结构
CRITICAL_SECTION g_cs;
DWORD WINAPI ServerThread1(PVOID pvParam)
{
//开始对共享资源的访问
EnterCriticalSection(&g_cs);
g_nSum = 0;
for(int n = 1; n
页:
[1]