在多处理器机器上获取 CPU 使用率
在多处理器机器上获取 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。