InitializeCriticalSectionAndSpinCount 函数 (synchapi.h)
初始化关键节对象并设置关键节的旋转计数。 当线程尝试获取锁定的关键部分时,该线程 会旋转:它进入循环,该循环将循环迭代旋转计数时间,检查是否释放了锁。 如果在循环完成之前未释放锁,线程将进入睡眠状态,等待锁释放。
语法
BOOL InitializeCriticalSectionAndSpinCount(
[out] LPCRITICAL_SECTION lpCriticalSection,
[in] DWORD dwSpinCount
);
参数
[out] lpCriticalSection
指向关键节对象的指针。
[in] dwSpinCount
关键部分对象的旋转计数。 在单处理器系统上,将忽略旋转计数,并将关键部分旋转计数设置为 0 (零) 。 在多处理器系统上,如果关键部分不可用,调用线程在对与关键部分关联的信号灯执行等待操作之前,将旋转 dwSpinCount 次。 如果关键部分在旋转操作期间变为空闲,调用线程将避免等待操作。
返回值
此函数始终成功并返回非零值。
Windows Server 2003 和 Windows XP: 如果函数成功,则返回值为非零值。 如果函数失败,则返回值为零 0
。 要获得更多的错误信息,请调用 GetLastError。 从 Windows Vista 开始, InitializeCriticalSectionAndSpinCount 函数始终成功,即使在内存不足的情况下也是如此。
注解
单个进程的线程可以使用关键节对象进行互斥同步。 无法保证线程获取关键节所有权的顺序。 但是,系统对所有线程都是公平的。
进程负责分配关键节对象使用的内存,它可以通过声明 类型为 CRITICAL_SECTION 的变量来执行此操作。 在使用关键部分之前,进程的某个线程必须初始化 对象。 随后可以通过调用 SetCriticalSectionSpinCount 函数来修改旋转计数。
初始化关键节对象后,进程的线程可以在 EnterCriticalSection、 TryEnterCriticalSection 或 LeaveCriticalSection 函数中指定对象,以提供对共享资源的互斥访问。 对于不同进程的线程之间的类似同步,请使用互斥对象。
无法移动或复制关键节对象。 进程也不得修改对象,但必须将其视为逻辑不透明。 仅使用关键节函数来管理关键节对象。 使用完关键部分后,调用 DeleteCriticalSection 函数。
必须先删除关键节对象,然后才能重新初始化它。 初始化已初始化的关键节会导致未定义的行为。
旋转计数对于持续时间短的关键部分非常有用,这些部分可能会经历高级别的争用。 考虑最坏的情况,其中 SMP 系统上的应用程序有两个或三个线程不断分配和释放堆中的内存。 应用程序使用关键部分序列化堆。 在最坏的情况下,关键节的争用是恒定的,每个线程都会对 WaitForSingleObject 函数进行处理密集型调用。 但是,如果正确设置了旋转计数,则调用线程不会在发生争用时立即调用 WaitForSingleObject 。 相反,如果在旋转操作期间释放关键节,调用线程可以获取关键节的所有权。
可以通过为持续时间较短的关键部分选择较小的旋转计数来显著提高性能。 例如,堆管理器对其每个堆的关键部分使用大约 4,000 个旋转计数。
若要编译使用此函数的应用程序, 请将 _WIN32_WINNT 定义为 0x0403
或更高版本。 有关详细信息,请参阅 使用 Windows 标头。
示例
有关使用 InitializeCriticalSectionAndSpinCount 的示例,请参阅 Using Critical Section Objects。
要求
最低受支持的客户端 | Windows XP [桌面应用 | UWP 应用] |
最低受支持的服务器 | Windows Server 2003 [桌面应用 | UWP 应用] |
目标平台 | Windows |
标头 | synchapi.h (包括 Windows Server 2003、Windows Vista、Windows 7、Windows Server 2008 Windows Server 2008 R2) |
Library | Kernel32.lib |
DLL | Kernel32.dll |