3

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);
    }
}
4

2 に答える 2

1

これは本当の答えではなく、提案です。レジストリにクエリを実行しているだけですが(書き込みはしていません)、複数のスレッドで何らかのデッドロックが発生しているのではないかと思います。

Windows の開発環境またはテスト環境がない場合は、この提案の価値を理解してください。おそらく、レジストリ呼び出しの周りでミューテックスを使用できます...それが実際に問題である場合、デッドロックの状況を緩和する可能性があります。

幸運を。

于 2010-03-29T17:26:35.753 に答える
1

環境問題に違いないと思います。32 ビットの Windows XP Professional から 64 ビットの Windows 7 Ultimate でこれを試したところ、問題なく動作しました。時折、1 つか 2 つのスレッドで RegQueryValueEx の呼び出しが ERROR_BUSY または ERROR_NOT_READY で失敗することがありますが、長い遅延は経験しませんでした。他の誰かがこれをテストしようとした場合に備えて、私は思わぬ障害に遭遇しました。HKEY_PERFORMANCE_DATA にリモートでアクセスするには、使用しているアカウントが Performance Monitor Users グループのメンバーである必要があります。また、リモート レジストリ サービスが実行されていることを確認します。

于 2010-04-01T01:49:44.873 に答える