gpt4 book ai didi

Windows 临界区 - 如何完全禁用旋转

转载 作者:行者123 更新时间:2023-12-03 11:07:14 26 4
gpt4 key购买 nike

我正在尝试通过不同的方法将 CRITICAL_SECTION 的旋转计数设置为零:

int main()
{
CRITICAL_SECTION cs;

::InitializeCriticalSection(&cs);
printf("Spin count by default %08X\n", cs.SpinCount);
::DeleteCriticalSection(&cs);

::InitializeCriticalSectionAndSpinCount(&cs, 0);
printf("Spin count with zero spin count init %08X\n", cs.SpinCount );
::DeleteCriticalSection(&cs);


::InitializeCriticalSectionEx(&cs, 0, 0);
printf("Spin count with zero spin count and flags init %08X\n", cs.SpinCount );
::DeleteCriticalSection(&cs);

::InitializeCriticalSection(&cs);
::SetCriticalSectionSpinCount(&cs, 0);
printf("Spin count after explicit reset to zero %08X\n", cs.SpinCount);
::DeleteCriticalSection(&cs);
}

在 Windows 7 中,所有结果都如预期的那样为 0。

在Windows 10中,除了最后一个,所有结果都是0x020007D0值。最后一个结果为 0x02000000

显然,0x07D0 是实际旋转计数(2000 十进制),0x02000000 是这些标志之一:

#define RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO         0x01000000
#define RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN 0x02000000
#define RTL_CRITICAL_SECTION_FLAG_STATIC_INIT 0x04000000
#define RTL_CRITICAL_SECTION_FLAG_RESOURCE_TYPE 0x08000000
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO 0x10000000

我担心 RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN 可能会导致临界区自旋,即使我使用 SetCriticalSectionSpinCount 要求它不自旋也是如此。

有什么方法可以不通过使用标准文档化 API 来定义 RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN 吗?

最佳答案

在窥视了实现之后,自己想出了答案。

InitializeCriticalSectionEx 与非零旋转计数一起使用时,RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN 标志未设置。所以这段代码输出00000001:

::InitializeCriticalSectionEx(&cs, 1, 0);
printf("Spin count after explicit one %08X\n", cs.SpinCount);
::DeleteCriticalSection(&cs);

一次旋转计数几乎为零旋转计数。此外,之后调用 SetCriticalSectionSpinCount 可以将其重置为零。所以这段代码输出00000000:

::InitializeCriticalSectionEx(&cs, 1, 0);
::SetCriticalSectionSpinCount(&cs, 0);
printf("Spin count after explicit one and then reset to zero %08X\n", cs.SpinCount);
::DeleteCriticalSection(&cs);

当然,应该有令人信服的理由来禁用旋转。默认情况下,正如@JonathanPotter 指出的那样,旋转是好的。否则它不会被设置为默认行为。所以我什至没有将禁用旋转的解决方案应用于我原来的问题。

另一方面,临界区的维护者可能无意不尊重传递给 InitializeCriticalSectionExInitializeCriticalSectionAndSpinCount 的零自旋计数。他们只是确保普通 InitializeCriticalSection 获得自动旋转计数。

关于Windows 临界区 - 如何完全禁用旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54765280/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com