Win32 临界区实现原理浅析
www.firnow.com 时间 : 2008-12-01 作者:佚名 编辑:辉辉 点击: [ 评论 ]
以下为引用:
// Global variable
CRITICAL_SECTION CriticalSection;
void main()
{
...// Initialize the critical section one time only.
if (!InitializeCriticalSectionAndSpinCount(&CriticalSection, 0x80000400) )
return;
...// Release resources used by the critical section object.
DeleteCriticalSection(&CriticalSection)
}DWORD WINAPI ThreadProc( LPVOID lpParameter )
{
...// Request ownership of the critical section.
EnterCriticalSection(&CriticalSection);// Access the shared resource.
// Release ownership of the critical section.
LeaveCriticalSection(&CriticalSection);...
}
首先看看构造和析构临界区结构的函数。
InitializeCriticalSection 函数(ntosdll esource.c:1210)实际上是调用 InitializeCriticalSectionAndSpinCount 函数(resource.c:1266)完成功能的,只不过传入一个值为0的初始Spin计数器;InitializeCriticalSectionAndSpinCount 函数主要完成两部分工作:初始化 RTL_CRITICAL_SECTION 结构和 RTL_CRITICAL_SECTION_DEBUG 结构。前者是临界区的核心结构,下面将着重讨论;后者是调试用结构,Matt 那篇文章里面分析的很清楚了,我这儿就不罗嗦了 :P
RTL_CRITICAL_SECTION结构在winnt.h中定义如下:
以下为引用:
typedef struct _RTL_CRITICAL_SECTION {
PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
//
// The following three fields control entering and exiting the critical
// section for the resource
//LONG LockCount;
LONG RecursionCount;
HANDLE OwningThread; // from the thread''s ClientId->UniqueThread
HANDLE LockSemaphore;
ULONG_PTR SpinCount; // force size on 64-bit systems when packed
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
InitializeCriticalSectionAndSpinCount 函数中首先对临界区结构进行了初始化
DebugInfo 字段指向初始化临界区时分配的RTL_CRITICAL_SECTION_DEBUG结构;
LockCount 字段是临界区中最重要的字段,初始值为-1,当临界区被获取(Hold)时此字段大于等于0;
RecursionCount 字段保存当前临界区所有者线程的获取缓冲区嵌套层数,初始值为0;
OwningThread 字段保存当前临界区所有者线程的句柄,初始值为0;
LockSemaphore 字段实际上是一个auto-reset的事件句柄,用于唤醒等待获取临界区的阻塞线程,初始值为0;
SpinCount 字段用于在多处理器环境下完成轻量级的CPU见同步,单处理器时没有使用(初始值为0),多处理器时设置为SpinCount参数值(最大为MAX_SPIN_COUNT=0x00ffffff)。此外 RtlSetCriticalSectionSpinCount 函数(resource.c:1374)的代码与这儿设置SpinCount的代码完全一样。