Я пытаюсь установить счетчик спинов для 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?
SetCriticalSectionSpinCount
также работает - он может установить количество вращений на ноль. Единственная проблема, которая у меня есть, это явно принудительный флагRTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN
. - person Alex Guteniev   schedule 19.02.2019TryEnterCriticalSection()
, если вы не хотите блокировать. Или вы можете использовать мьютекс. Обратите внимание, чтоRTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN
не задокументировано; похоже, нет никакой информации о том, для чего это на самом деле. - person Jonathan Potter   schedule 20.02.2019TryEnterCriticalSection
не вариант, так как я хочу заблокировать, если объект принадлежит. Мьютекс WinAPI также не вариант, так как я не хочу переходить в ядро, когда объект теперь принадлежит. Ближайшей альтернативой является Slim Reader/Writer Lock, когда он заблокированAcquireSRWLockExclusive
/ReleaseSRWLockExclusive
, он, похоже, делает именно то, что мне нужно, за исключением того, что он не поддерживает рекурсию. Реализацияstd::mutex
из C++,boost::mutex
или Visual Studio также ведет себя так, как я хочу (и есть даже их рекурсивные версии). Тем не менее, мой вопрос касается контроля над поведением критической секции. - person Alex Guteniev   schedule 20.02.2019