Сколько CRITICAL_SECTION можно создать? - PullRequest
9 голосов
/ 01 июня 2009

Есть ли ограничение на количество критических секций, которые я могу инициализировать и использовать?

Мое приложение создает несколько (пару тысяч) объектов, которые должны быть поточно-ориентированными. Если у меня есть критический раздел в каждом, будет ли он использовать слишком много ресурсов?

Я подумал, что, поскольку мне нужно объявить свой собственный объект CRITICAL_SECTION, я не трачу ресурсы ядра, как если бы это было с Win32 Mutex или Event? Но у меня просто ноющее сомнение ...?

Если честно, не все эти объекты, вероятно, нуждаются в , чтобы быть потокобезопасными для моего приложения, но критическая секция находится в каком-то низкоуровневом базовом классе в библиотеке, и мне нужна пара тысяч из них!

У меня может быть возможность изменить эту библиотеку, поэтому мне было интересно, есть ли способ лениво создать (и затем использовать с этого момента) критическую секцию только тогда, когда я обнаружу, что объект используется из другого потока для тот, в котором он был создан? Или это то, что Windows сделает для меня?

Ответы [ 3 ]

9 голосов
/ 01 июня 2009

Нет ограничений на число CRITICAL_SECTION структур , которые вы можете объявить - это просто структуры данных POD на самом низком уровне. Может быть некоторое ограничение на число, которое вы можете инициализировать с InitializeCriticalSection(). Согласно документации, это может вызвать исключение STATUS_NO_MEMORY в Windows 2000 / XP / Server 2003, но очевидно, что оно гарантированно будет успешным в Vista. Они не занимают никаких ресурсов ядра, пока вы не инициализируете их (если они вообще их используют).

Если вы обнаружите, что возникает исключение STATUS_NO_MEMORY, вы можете попробовать только инициализировать CRITICAL_SECTION для данного объекта, если есть вероятность, что он может быть использован в нескольких потоках. Если вы знаете, что конкретный объект будет использоваться только с одним потоком, установите флаг, а затем пропустите все вызовы InitializeCriticalSection(), EnterCriticalSection(), LeaveCriticalSection() и DeleteCriticalSection().

7 голосов
/ 01 июня 2009

Если вы внимательно прочитали документацию для IntializeCriticalSectionWithSpinCount () , становится ясно, что каждый критический раздел поддерживается объектом Event, хотя API для критических разделов обрабатывает их как непрозрачные структуры. Кроме того, комментарий «Windows 2000» к параметру dwSpinCount гласит, что объект события «выделяется по требованию».

Я не знаю ни одной документации, в которой говорится, какие условия удовлетворяют «по требованию», но я подозреваю, что он не создается, пока поток не блокируется при входе в критическую секцию. Для критических участков со счетчиком вращений этого может не произойти, пока ожидание вращения не будет исчерпано.

Говоря эмпирически, я работал над приложением, которое, как мне известно, создало не менее 60 000 живых COM-объектов, каждый из которых синхронизируется с собственным CRITICAL_SECTION. Я никогда не сталкивался с ошибками, свидетельствующими о том, что я исчерпал запас объектов ядра.

0 голосов
/ 01 июня 2009

Afaik большинство типов дескрипторов / ресурсов в Windows ограничены объемом памяти или максимальным значением, что бы ни было на первом месте. (теоретически на 64-битном максинте может случиться).

Иногда слабые тексты, которые вы найдете на эту тему, обычно относятся только к Win9x, у которого были некоторые ограничения. (Всего 64 тыс. Объектов ядра)

...