Я вижу странную вещь при подключении к реестру производительности в 64-разрядных выпусках Windows. Вся программа останавливается и callstacks становится нечитаемым. По истечении длительного времени попытка соединения прерывается, и все возвращается в нормальное состояние.
Единственное решение состоит в том, чтобы убедиться, что только один поток одновременно запрашивает удаленный реестр, если только удаленная машина не является 32-битной Windows XP, 2003, 2000, тогда вы можете использовать столько потоков, сколько захотите. *
У кого-нибудь есть техническое объяснение, почему это может происходить? Я потратил 2-3 дня на поиск в Интернете, ничего не придумав.
Вот тестовая программа, сначала запустите ее с одним потоком (подключаясь к 64-битной Windows), затем удалите комментарий в tmain и запустите его с 4 потоками. Запуск его с одним потоком работает как положено, запуск с 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);
}
}