在C/C++代碼中使用windows效能監控器

來源:互聯網
上載者:User

《編程之美》中的“讓CPU佔用率曲線聽你指揮”一題,作者給出的解法3非常清晰簡潔。其思想就是直接查詢當前CPU佔用率,若過高則Sleep一段時間,否則一直迴圈。代碼使用C#編寫。於是自己想將這一思路使用C/C++來實現。
那麼首先需要查清楚windows提供了哪些操作效能監控器(perfmon.msc)的API。在網上搜尋一下,在vckbase上有一篇文章恰好是講解這一主題的。這些操作效能監控器的API都以pdh開頭。只要知道這一點,就可以在MSDN上查到完整資料。
在MSDN中的索引中輸入PDH,列出的第一條主題就是:Platform SDK: Performance Monitoring—Using the PDH Interface.這篇概述文章中描述了PDH可以做什麼以及如何使用它們。使用PDH介面操作效能監控器的方法可以概括為以下五個步驟:
1. 建立一個查詢(Create a query)。相關的API是PdhOpenQuery。
2. 在已建立的查詢中添加一個或多個計數器(Add counters to the query)。相關的API是PdhAddCounter。這個API需要一個描述計數器的字串參數。MSDN上給出了四種構造符合文法的字串的方法。其中最容易的方法是使用PdhMakeCounterPath函數。
3. 收集效能資料(collect the performance data)。與此相關的API是PdhCollectQueryData。
4. 處理這此收集到的效能資料(Process the performance data)。與此相關的有數個API。PdhGetFormattedCounterValue這個函數用來獲得指定格式的資料。
5. 完成任務後,關閉這個查詢(Close the query)。相關的API是PdhCloseQuery。
以上五步中第二步構造描述計數器的字串有些陌生。它牽扯到一個資料結構,這個資料結構的定義如下:typedef struct _PDH_COUNTER_PATH_ELEMENTS {<br /> LPTSTR szMachineName;<br /> LPTSTR szObjectName;<br /> LPTSTR szInstanceName;<br /> LPTSTR szParentInstance;<br /> DWORD dwInstanceIndex;<br /> LPTSTR szCounterName;<br />} PDH_COUNTER_PATH_ELEMENTS, *PPDH_COUNTER_PATH_ELEMENTS;  

  如果不知道如何填充這個資料結構,最好的辦法就是開啟效能監控器(開始——運行——輸入“perfmon.msc”),在圖表框中右擊,選擇添加計數器,在彈出的“添加計數器”對話方塊中,可以通過下柆列表或列表框選擇電腦(資料結構的szMachineName項)、效能物件(szObjectName)、選擇計數器(與Object對應的szCounterName)、選擇範例(szInstanceName)。可以照著填充。
   在我的程式中需要擷取CPU使用率。所以選擇的對象是Processor,計數器是% Processor Time,範例是_Total。完整的程式碼如下:#undef UNICODE<br />#undef _UNICODE<br />#include <windows.h><br />#include <tchar.h><br />#include <stdio.h><br />#include <pdh.h></p><p>#pragma comment(lib, "pdh.lib")</p><p>HQUERY hQuery = NULL;</p><p>// 處理ctrl-c異常<br />BOOL WINAPI HandlerRoutine(<br /> DWORD dwCtrlType // control signal type<br /> ) {<br /> if(dwCtrlType == CTRL_C_EVENT) {<br /> printf("ctrl c exception/n");<br /> if(hQuery) PdhCloseQuery(hQuery);<br /> }<br /> return false;<br />}</p><p>int main() {<br />SetConsoleCtrlHandler(HandlerRoutine, TRUE);</p><p>PDH_STATUS pdhStatus;</p><p>// open query<br />pdhStatus = PdhOpenQuery(0, 0, &hQuery);<br />if(pdhStatus != ERROR_SUCCESS) {<br />printf("PdhOpenQuery failed/n");<br />exit(1);<br />}</p><p>// construct a counter path<br />PDH_COUNTER_PATH_ELEMENTS pcpe;<br />TCHAR szFullPathBuffer[MAX_PATH] = TEXT("");<br />DWORD dwSize = sizeof(szFullPathBuffer);</p><p>pcpe.szMachineName = TEXT("WANGHAIBIN");<br />pcpe.szObjectName = TEXT("Processor");<br />pcpe.szInstanceName = TEXT("_Total");<br />pcpe.szCounterName = TEXT("% Processor Time");<br />pcpe.dwInstanceIndex = -1;<br />pcpe.szParentInstance = NULL;</p><p>pdhStatus = PdhMakeCounterPath(&pcpe, szFullPathBuffer, &dwSize, 0);<br />if(pdhStatus != ERROR_SUCCESS) {<br />printf("PdhMakeCounterPath failed/n");<br />goto exit_prog;<br />}<br />_tprintf(TEXT("path: %s/n"), szFullPathBuffer);</p><p>// add a counter<br />HCOUNTER hCounter;<br />pdhStatus = PdhAddCounter(hQuery, szFullPathBuffer, 0, &hCounter);<br />//pdhStatus = PdhAddCounter(hQuery, TEXT("//Processor(_Total)//% Processor Time"), 0, &hCounter);<br />if(pdhStatus != ERROR_SUCCESS) {<br />printf("PdhAddCounter failed/n");<br />goto exit_prog;<br />}</p><p>// collect query data<br />pdhStatus = PdhCollectQueryData(hQuery);<br />//pdhStatus = PdhCollectQueryDataEx(hQuery, 1, NULL);<br />if(pdhStatus != ERROR_SUCCESS) {<br />printf("PdhCollectQueryData failed/n");<br />goto exit_prog;<br />}</p><p>// get counter value<br />PDH_FMT_COUNTERVALUE pfc;<br />DWORD dwOpt;</p><p>pdhStatus = PdhGetFormattedCounterValue(<br />hCounter,PDH_FMT_DOUBLE,&dwOpt,&pfc);<br />while(pdhStatus == ERROR_SUCCESS) {<br />//printf("%lf/n", pfc.doubleValue);<br />pdhStatus = PdhCollectQueryData(hQuery);<br />PdhGetFormattedCounterValue(hCounter, PDH_FMT_DOUBLE, &dwOpt, &pfc);<br />}</p><p>exit_prog:<br />PdhCloseQuery(hQuery);<br />return 0;<br />}

    需要注意的是,上面的% Processor Time中的%和Processor之間有一個空格。不要寫錯了。
VCKBASE的那篇文章連結:http://www.vckbase.com/document/viewdoc/?id=1434

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.