I'm seeing a weird thing when connecting to the performance registry on 64 bit editions of Windows. The whole program stalls and callstacks becomes unreadable. After a long timeout, the connection attempts aborts 开发者_C百科and everything goes back to normal.
The only solution is to make sure that only one thread at the time queries the remote registry, unless the remote machine is a 32 bit Windows XP, 2003, 2000 , then you can use as many threads as you like.
Have anyone a technical explanation why this might be happening ? I've spent 2-3 days searching the web without coming up with anything.
Here is a test program, run it first with one thread (connecting to a 64 bit Windows), then remove the comment in tmain and run it with 4 threads. Running it with one thread works as expected, running with 4, returns ERROR_BUSY (dwRet == 170) after stalling for a while.
Remember to set a remote machine correctly in RegConnectRegistry before running the program.
#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);
}
}
This is not really an answer, but a suggestion. Even though you are only querying the registry (not writing), I'm wondering if you are producing some kind of dead-lock with the multiple threads.
Lacking a Windows development or testing environment, take this suggestion for what its worth: perhaps you could use mutexes around the registry calls... that may relieve any deadlock situation, if that is indeed the problem.
Good luck.
I think it must be an environmental issue. I just tried this from 32-bit Windows XP Professional to 64-bit Windows 7 Ultimate and it worked fine. Occasionally on a thread or two a call to RegQueryValueEx would fail with either ERROR_BUSY or ERROR_NOT_READY, but I never experienced any long delays. In case anybody else tries to test this, I ran into a snag; the account you are using must be a member of the Performance Monitor Users group in order to remotely access HKEY_PERFORMANCE_DATA. Also ensure the Remote Registry Service is running.
精彩评论