Проблема с подключением RegConnectRegistry к 64-битным компьютерам - PullRequest
3 голосов
/ 08 марта 2010

Я вижу странную вещь при подключении к реестру производительности в 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);
    }
}

Ответы [ 2 ]

1 голос
/ 01 апреля 2010

Я думаю, что это проблема окружающей среды. Я только что попробовал это с 32-битной Windows XP Professional до 64-битной Windows 7 Ultimate, и все работало нормально. Иногда в потоке или в два раза вызов RegQueryValueEx завершается с ошибкой либо с ERROR_BUSY, либо с ERROR_NOT_READY, но я никогда не испытывал длительных задержек. В случае, если кто-то еще попытается проверить это, я столкнулся с проблемой; используемая учетная запись должна быть членом группы «Пользователи системного монитора» для удаленного доступа к HKEY_PERFORMANCE_DATA. Также убедитесь, что служба удаленного реестра работает.

1 голос
/ 29 марта 2010

Это на самом деле не ответ, а предложение. Даже если вы только запрашиваете реестр (не записываете), мне интересно, если вы производите какую-то взаимоблокировку с несколькими потоками.

Не имея среды разработки или тестирования Windows, примите это предложение по достоинству: возможно, вы могли бы использовать мьютексы вокруг вызовов реестра ... что может устранить любую тупиковую ситуацию, если это действительно проблема .

Удачи.

...