关键代码段与循环锁
当线程访问另一个线程拥有的关键代码段时,调用线程就立即被置于等待状态。即该线程从用户态转入内核态。调用
EnterCriticalSection
函数时它使用循环锁进行循环,设法多次取得该资源。只有每次都失败时,该线程才转入内核态以便进入等待状态。
BOOL InitializeCriticalSectionAndSpinCount(PCRITICAL_SECTION pcs, DWORD dwSpinCount);
将循环锁放入关键代码,第一个参数是关键代码段结构的地址,第二个参数是使线程等待之前它试图获得资源时想要循环锁循环迭代的次数。可以是
0
至
0 x 0 0 FFFFFF
之间的任何数字(单处理器计算机上时该参数忽略)。
DWORD SetCriticalSectionSpinCount(PCRITICAL_SECTION pcs, DWORD dwSpinCount);
用于改变设置关键代码段的循环次数(指导原则,保护对进程的堆栈进行访问的关键代码段使用的循环次数是
4000
次)。
InitializeCriticalSection
函数可能运行失败,它分配了一个内存块以便系统得到一些内部调试信息。如果该内存的分配失败,就会出现一个
STATUS_NO_MEMORY
异常情况。可以使用结构化异常处理来捕捉这个异常。
如果两个或多个线程同时争用关键代码段,则关键代码段将使用一个事件内核对象。如果内存不足,关键代码段可能被争用同时系统可能无法创建必要的事件内核对象。这时
EnterCriticalSention
函数将会产生一个
EXCEPTION_INVALID_HANDLE
异常。可以使用结构化异常处理方法来跟踪错误。也可以用
InitializeCriticalSectionAndSpinCount
函数
,
确保设置了
dwSpinCount
参数的高信息位。当该函数发现高信息位已经设置时,它就创建该事件内核对象,并在初始化时将它与关键代码段关联起来。如果事件无法创建,该函数返回
FA L S E
。