Microsoft は実際に、InitializeCriticalSection
Vista、Windows Server 2008、そしておそらく Windows 7 での動作方法を変更し
ました。一連の CS を割り当てるときに、デバッグ情報に使用されるメモリを保持する「機能」を追加しました。より多く割り当てるほど、より多くのメモリが保持されます。それは漸近的であり、最終的には横ばいになる可能性があります (完全に購入されたわけではありません)。
この「機能」を回避するには、新しい API InitalizeCriticalSectionExを使用してフラグを渡す必要がありCRITICAL_SECTION_NO_DEBUG_INFO
ます。
これの利点は、多くの場合、実際に待機することなくスピンカウントのみが使用されるため、高速になる可能性があることです。
欠点は、古いアプリケーションに互換性がない可能性があることです、コードを変更する必要があり、現在はプラットフォームに依存しています (使用するバージョンを決定するには、バージョンを確認する必要があります)。また、必要に応じてデバッグすることもできなくなります。
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;
}
-...このバッチ ファイルを実行します (サーバー SDK の sleep.exe が必要です)。
@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
-...そして、起動された 300 のインスタンスに到達する前に、8GB およびクアッド CPU コアを備えた Win2008 サーバーがフリーズするのを確認します。
-...Windows 2003 サーバーで繰り返し、それが魅力的に処理されることを確認します。