InitializeCriticalSectionEx 函数 (synchapi.h)

使用旋转计数和可选标志初始化关键节对象。

语法

BOOL InitializeCriticalSectionEx(
  [out] LPCRITICAL_SECTION lpCriticalSection,
  [in]  DWORD              dwSpinCount,
  [in]  DWORD              Flags
);

参数

[out] lpCriticalSection

指向关键节对象的指针。

[in] dwSpinCount

关键部分对象的旋转计数。 在单处理器系统上,将忽略旋转计数,并将关键部分旋转计数设置为 0 (零) 。 在多处理器系统上,如果关键部分不可用,则调用线程在对与关键节关联的信号灯执行等待操作之前,调用线程会旋转 dwSpinCount 次。 如果关键部分在旋转操作期间变为空闲,调用线程将避免等待操作。

[in] Flags

此参数可以是 0 或以下值。

含义
CRITICAL_SECTION_NO_DEBUG_INFO 关键部分是在没有调试信息的情况下创建的。

返回值

如果该函数成功,则返回值为非零值。

如果函数失败,则返回值为零 (0)。 要获得更多的错误信息,请调用 GetLastError。

注解

单个进程的线程可以使用关键节对象进行互斥同步。 无法保证线程获取关键节所有权的顺序,但是,系统对所有线程都是公平的。

进程负责分配关键节对象使用的内存,可以通过声明 CRITICAL_SECTION类型的变量来执行此操作。 在使用关键部分之前,进程的某个线程必须初始化 对象。 随后可以通过调用 SetCriticalSectionSpinCount 函数来修改旋转计数。

初始化关键节对象后,进程的线程可以在 EnterCriticalSectionTryEnterCriticalSectionLeaveCriticalSection 函数中指定对象,以提供对共享资源的互斥访问。 对于不同进程的线程之间的类似同步,请使用互斥对象。

无法移动或复制关键节对象。 进程也不能修改 对象,但必须将其视为逻辑不透明。 仅使用关键节函数来管理关键节对象。 使用完关键部分后,调用 DeleteCriticalSection 函数。

必须先删除关键节对象,然后才能重新初始化它。 初始化已初始化的关键节会导致未定义的行为。

旋转计数对于持续时间短的关键部分非常有用,这些部分可能会经历高级别的争用。 请考虑最坏的情况,即 SMP 系统上的应用程序有两个或三个线程不断分配和释放堆中的内存。 应用程序使用关键部分序列化堆。 在最坏的情况下,关键节的争用是恒定的,并且每个线程都会对 WaitForSingleObject 函数进行处理密集型调用。 但是,如果正确设置了旋转计数,则调用线程不会在发生争用时立即调用 WaitForSingleObject 。 相反,如果关键节在旋转操作期间释放,调用线程可以获取该节的所有权。

可以通过为持续时间较短的关键部分选择较小的旋转计数来显著提高性能。 堆管理器对其每个堆关键部分使用大约 4000 个旋转计数。 这在几乎所有最坏情况下都提供了出色的性能和可伸缩性。

要求

要求
最低受支持的客户端 Windows Vista [桌面应用 | UWP 应用]
最低受支持的服务器 Windows Server 2008 [桌面应用 | UWP 应用]
目标平台 Windows
标头 synchapi.h (包括 Windows 7 上的 Windows.h、Windows Server 2008 Windows Server 2008 R2)
Library Kernel32.lib
DLL Kernel32.dll

另请参阅

关键节对象

DeleteCriticalSection

VBS enclave 中可用的 Vertdll API