64 ビット エディションの Windows でパフォーマンス レジストリに接続すると、奇妙な現象が発生します。プログラム全体が停止し、コールスタックが読み取れなくなります。長いタイムアウトの後、接続試行は中止され、すべてが正常に戻ります。
唯一の解決策は、リモート マシンが 32 ビットの Windows XP、2003、2000 でない限り、一度に 1 つのスレッドだけがリモート レジストリにクエリを実行するようにすることです。その後は、必要な数のスレッドを使用できます。
なぜこれが起こっているのか、技術的な説明はありますか? 何も思いつかずに2〜3日ウェブを検索しました。
これはテスト プログラムです。最初に 1 つのスレッドで実行し (64 ビット Windows に接続)、次に tmain のコメントを削除して 4 つのスレッドで実行します。1 つのスレッドで実行すると期待どおりに動作し、4 で実行すると、しばらくストールした後に ERROR_BUSY (dwRet == 170) が返されます。
プログラムを実行する前に、RegConnectRegistry でリモート マシンを正しく設定することを忘れないでください。
#define TOTALBYTES 8192
#define BYTEINCREMENT 4096
void PerfmonThread(void *pData)
{
DWORD BufferSize = TOTALBYTES;
DWORD cbData;
DWORD dwRet;
PPERF_DATA_BLOCK PerfData = (PPERF_DATA_BLOCK) malloc( BufferSize );
cbData = BufferSize;
printf("\nRetrieving the data...");
HKEY hKey;
DWORD dwAccessRet = RegConnectRegistry(L"REMOTE_MACHINE",HKEY_PERFORMANCE_DATA,&hKey);
dwRet = RegQueryValueEx( hKey,L"global",NULL,NULL,(LPBYTE) PerfData, &cbData );
while( dwRet == ERROR_MORE_DATA )
{
// Get a buffer that is big enough.
BufferSize += BYTEINCREMENT;
PerfData = (PPERF_DATA_BLOCK) realloc( PerfData, BufferSize );
cbData = BufferSize;
printf(".");
dwRet = RegQueryValueEx( hKey,L"global",NULL,NULL,(LPBYTE) PerfData,&cbData );
}
if( dwRet == ERROR_SUCCESS )
printf("\n\nFinal buffer size is %d\n", BufferSize);
else
printf("\nRegQueryValueEx failed (%d)\n", dwRet);
RegCloseKey(hKey);
}
int _tmain(int argc, _TCHAR* argv[])
{
_beginthread(PerfmonThread,0,NULL);
/* _beginthread(PerfmonThread,0,NULL);
_beginthread(PerfmonThread,0,NULL);
_beginthread(PerfmonThread,0,NULL);
*/
while(1)
{
Sleep(2000);
}
}