Windows重要部分 - 如何完全禁用纺(Windows Critical Section - h

2019-09-28 00:26发布

我试图为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?

Answer 1:

偷看实施后,想出回答自己。

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 Critical Section - how to disable spinning completely