Microsoft действительно изменила способ работы InitializeCriticalSection
в Vista, Windows Server 2008 и, вероятно, также в Windows 7.
Они добавили «функцию» для сохранения некоторой памяти, используемой для отладочной информации, когда вы выделяете кучу CS. Чем больше вы выделяете, тем больше памяти сохраняется. Это может быть асимптотическим и в конечном итоге расплющенным (не полностью купленным к этому).
Чтобы избежать этой «функции», вы должны использовать новый API InitalizeCriticalSectionEx и передать флаг CRITICAL_SECTION_NO_DEBUG_INFO
.
Преимущество этого состоит в том, что это может быть быстрее, поскольку очень часто будет использоваться только spincount без необходимости ждать.
Недостатки в том, что ваши старые приложения могут быть несовместимы , вам нужно изменить код, и теперь он зависит от платформы (вы должны проверить версию, чтобы определить, какую из них использовать). А также вы теряете возможность отладки, если вам нужно.
Тестовый набор для замораживания Windows Server 2008:
создать этот пример C ++ как CSTest.exe
#include "stdafx.h"
#include "windows.h"
#include <iostream>
using namespace std;
void TestCriticalSections()
{
const unsigned int CS_MAX = 5000000;
CRITICAL_SECTION* csArray = new CRITICAL_SECTION[CS_MAX];
for (unsigned int i = 0; i < CS_MAX; ++i)
InitializeCriticalSection(&csArray[i]);
for (unsigned int i = 0; i < CS_MAX; ++i)
EnterCriticalSection(&csArray[i]);
for (unsigned int i = 0; i < CS_MAX; ++i)
LeaveCriticalSection(&csArray[i]);
for (unsigned int i = 0; i < CS_MAX; ++i)
DeleteCriticalSection(&csArray[i]);
delete [] csArray;
}
int _tmain(int argc, _TCHAR* argv[])
{
TestCriticalSections();
cout << "just hanging around...";
cin.get();
return 0;
}
-... Запустить этот пакетный файл (требуется файл sleep.exe с сервера SDK)
@rem you may adapt the sleep delay depending on speed and # of CPUs
@rem sleep 2 on a duo-core 4GB. sleep 1 on a 4CPU 8GB.
@for /L %%i in (1,1,300) do @echo %%i & @start /min CSTest.exe & @sleep 1
@echo still alive?
@pause
@taskkill /im cstest.* /f
-... и увидите сервер Win2008 с 8 ГБ и четырехъядерным процессором, который зависает до достижения 300 запущенных экземпляров.
-... повторите на сервере Windows 2003 и убедитесь, что он обрабатывает его как очарование.