65.9K
CodeProject 正在变化。 阅读更多。
Home

在多处理器机器上获取 CPU 使用率

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.59/5 (13投票s)

2005年5月31日

Ms-PL

1分钟阅读

viewsIcon

173525

downloadIcon

3715

在多处理器机器上获取 CPU 使用率。

引言

自从我在 Windows 2000 上看到“性能”应用程序以来,我就想知道是否有办法/Windows API 以编程方式确定多处理器机器中每个单独 CPU 的 CPU 使用率。虽然有很多关于获取 CPU 使用率的文章,但当涉及到多处理器机器时,没有一篇有帮助。

在 MSDN 中进行了一些研究后,我发现 WMI(Windows 管理和仪器化)有一些性能计数器类。在这种情况下,我选择使用 Win32_PerfRawData_PerfOS_Processor 类,因为它支持 Windows 2000 及更高版本。

如何使用它?

按照以下七个步骤操作

步骤 1:初始化 COM

CoInitializeEx(0, COINIT_MULTITHREADED);

步骤 2:设置 COM 安全级别

CoInitializeSecurity(
        NULL, 
        -1,                          // COM authentication
        NULL,                        // Authentication services
        NULL,                        // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
        RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
        NULL,                        // Authentication info
        EOAC_NONE,                   // Additional capabilities 
        NULL                         // Reserved
        );

步骤 3:获取指向 WMI 的初始定位器

   IWbemLocator *pLoc = NULL;

   hres = CoCreateInstance(
        CLSID_WbemLocator,             
        0, 
        CLSCTX_INPROC_SERVER, 
        IID_IWbemLocator, (LPVOID *) &pLoc);

步骤 4:通过 IWbemLocator::ConnectServer 方法连接到 WMI

    IWbemServices *pSvc = NULL;
 
    // Connect to the root\cimv2 namespace with
    // the current user and obtain pointer pSvc
    // to make IWbemServices calls.
    hres = pLoc->ConnectServer(
         _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
         NULL,                    // User name. NULL = current user
         NULL,                    // User password. NULL = current
         0,                       // Locale. NULL indicates current
         NULL,                    // Security flags.
         0,                       // Authority (e.g. Kerberos)
         0,                       // Context object 
         &pSvc                    // pointer to IWbemServices proxy
         );

步骤 5:在代理上设置安全级别

CoSetProxyBlanket(
       pSvc,                        // Indicates the proxy to set
       RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
       RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
       NULL,                        // Server principal name 
       RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
       RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
       NULL,                        // client identity
       EOAC_NONE                    // proxy capabilities 
    );

步骤 6:使用 IWbemServices 指针向 WMI 发出请求

    IEnumWbemClassObject* pEnumerator = NULL;
    HRESULT hres = pSvc->ExecQuery(
        bstr_t("WQL"), 
        bstr_t("SELECT * FROM Win32_PerfRawData_PerfOS_Processor"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
        NULL,
        &pEnumerator);

步骤 7:从步骤 6 中的查询中获取数据。

    IWbemClassObject *pclsObj;
    while (1)
    {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

        if(0 == uReturn)
        {
            break;
        }

          VARIANT vtProp;
          VariantInit(&vtProp);

          hr = pclsObj->Get(L"PercentProcessorTime", 0, &vtProp, 0, 0);

          // Use it

           hr = pclsObj->Get(L"TimeStamp_Sys100NS", 0, &vtProp, 0, 0);

          // Use it
    }

注意

我已尝试使附带项目的源代码保持简单。因此,我将处理器数量作为输入,尽管您可以使用 GetSystemInfo Win32 API 以编程方式获取处理器数量。

我已在运行于双处理器机器上的 Microsoft Windows 2000 Professional OS 上对其进行了测试。它也应该适用于 Windows XP/ Windows 2003 Server。

© . All rights reserved.