在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);
}
}
答案 0 :(得分:1)
这不是一个真正的答案,而是一个建议。即使你只是查询注册表(不是写),我想知道你是否正在使用多线程产生某种死锁。
缺乏Windows开发或测试环境,请考虑以下建议:或许您可以在注册表调用周围使用互斥锁... 可以减轻任何死锁情况,如果确实是问题
祝你好运。答案 1 :(得分:1)
我认为这一定是一个环境问题。我刚尝试从32位Windows XP专业版到64位Windows 7旗舰版,它运行良好。偶尔在一个或两个线程上,对RegQueryValueEx的调用会因ERROR_BUSY或ERROR_NOT_READY而失败,但我从未经历任何长时间的延迟。如果有人试图测试这个,我遇到了障碍;您正在使用的帐户必须是Performance Monitor Users组的成员才能远程访问HKEY_PERFORMANCE_DATA。还要确保远程注册表服务正在运行。