windows - Windows 关键部分 - 如何完全禁用旋转
问题描述
我正在尝试通过不同的方法将 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
.
有没有办法不RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN
使用标准文档 API 来定义?
解决方案
在查看了实现之后,自己想出了答案。
当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 指出的那样,旋转很好。否则它不会被设置为默认行为。所以我什至没有将禁用旋转的解决方案应用于我原来的问题。
另一方面,临界区的维护者可能无意不尊重传递给InitializeCriticalSectionEx
or的零自旋计数InitializeCriticalSectionAndSpinCount
。他们只是确保平原InitializeCriticalSection
获得自动旋转计数。
推荐阅读
- math - 缩放旋转椭圆的 X 轴
- visual-studio - 无法使用 Visual Studio Live Share 在客户端启动项目窗口
- python-2.7 - pip install mock 有效,但 import mock 无效
- javascript - 如何通过 esri js 中的 javascript api 访问安全的 webscene(无需向用户询问凭据。)
- python - 当我在 python tkinter 中另存为 pdf 时,它显示错误
- docker - 在构建 VSCode 开发容器时使用主机网络
- powershell - 混合纠缠发现和运行变量
- asp.net-core - 为什么我的 URL 在我按 Enter 之前得到处理?
- mysql - 使用子查询优化 SQL 查询
- php - 无法安装学说/mongodb-odm-bundle