System performance counters

Source: Internet
Author: User
* System performance counters
Quoted by wanfustudio from csdn: http://blog.csdn.net/wanfustudio
Trackback: http://hi.baidu.com/wlzqi

I. Introduction to performance counters:

System performance counters? Maybe a lot of friends have never used it! (Ugly) This feature is powerful. As its name suggests, it is something that can count Performance Indicators of Windows systems. In Windows 2000 and above, if it is installed by default, it will bring a performance counter program, you can see this program in "Control Panel-> Management-> performance.

Windows system performance counters can track hundreds of system performance indicators in real time. Right-click the system program's drawing interface and select "add counter" to view all the items that can be counted. I often see some new friends in the forum asking me how to implement the task manager and how to obtain the CPU usage of each process in real time. memory usage... so I think using the system performance counter should be the best choice. For more information, see the following section.

II. Specific implementation:

Related API introduction and example code:

1. pdhopenquery: Open the counter

Pdh_status pdhstatus;
Hquery phquery = NULL;
Hcounter pcounterhandle = NULL;
Pdhstatus = pdhopenquery (0, 0, & phquery );
If (pdhstatus! = Error_success) return false;
// Allocate counter handle Space
Pcounterhandle = (hcounter *) globalalloc (gptr, sizeof (hcounter ));
If (pcounterhandle = NULL) return false;

2. pdhclosequery: Close the counter
Pdhstatus = pdhclosequery (phquery );
If (pdhstatus! = Error_success) return false;

3. pdhenumobjects: enumeration counting item. This function has six parameters (see msdn for details)
Prototype:
Pdh_status pdhenumobjects (
Lpctstr szdatasource, // must be null
Lpctstr szmachinename, // machine name. If it is a local machine, it can be null.
Lptstr mszobjectlist, // receives the buffer for all available counting items
Lpdword pcchbufferlength, // buffer size (if it is 0, this value returns the required size)
DWORD dwdetaillevel, // Information Retrieval level
Bool brefresh // It is generally set to true.
);
Example:
Lptstr lpsobjectlistbuffer = NULL;
Lptstr lpsthisobject = NULL;
DWORD dwobjectlistsize = 0;
// Set the buffer size to 0 in the first step to obtain the required buffer size.
Pdhstatus = pdhenumobjects (

Null,
Lpcsmachinename,
Lpsobjectlistbuffer,
& Dwobjectlistsize,
Perf_detail_wizard,
True );
If (pdhstatus! = Error_success | pdhstatus! = Pdh_more_data) return false;
// After obtaining the buffer size, allocate the cache area memory
Lpsobjectlistbuffer = (lptstr) malloc (dwobjectlistsize + 1 );
If (lpsobjectlistbuffer = NULL) return false;
// The second step is to call the enumeration function to start enumeration counting items.
Pdhstatus = pdhenumobjects (

Null,
Lpcsmachinename,
Lpsobjectlistbuffer,
& Dwobjectlistsize,
Perf_detail_wizard,
True );
If (pdhstatus! = Error_success) return false;
// Save the buffer address
Lpsthisobject = lpsobjectlistbuffer;
// Print all available counting items
For (; * lpsthisobject! = 0; lpsthisobject + = (lstrlen (lpsthisobject) + 1 ))
{
Printf (lpsthisobject );
}
If (lpsobjectlistbuffer)
{
Free (lpsobjectlistbuffer );
Lpsobjectlistbuffer = NULL;
Dwobjectlistsize = 0;
}

4. pdhenumobjectitems: enumeration counter and instance
Prototype:
Pdh_status pdhenumobjectitems (

Lpctstr szdatasource, // must be null
Lpctstr szmachinename, // machine name. If it is a local machine, it can be null.
Lpctstr szobjectname, // count items (all available items can be obtained through the pdhenumobjects function)
Lptstr mszcounterlist, // counter Buffer
Lpdword pcchcounterlistlength, // counter buffer size
Lptstr mszinstancelist, // count instance Buffer
Lpdword pcchinstancelistlength, // count the instance buffer size
DWORD dwdetaillevel, // Information Retrieval level
DWORD dwflags // set to true
);
For example, the method of this function is the same as that of the previous function (pdhenumobjects). For details, see msdn or the test project code attached to this article.

5. pdhaddcounter: Add a counter
When calculating the system information that you are interested in, you must first add the corresponding counters.
Prototype:
Pdh_status pdhaddcounter (
Pdh_hquery hquery, // handle opened for pdhopenquery
Lpctstr szfullcounterpath, // counter path (maximum length: pdh_max_counter_path)
Dword_ptr dwuserdata, // set it to 0
Pdh_hcounter * phcounter // counter handle Space (allocated after the pdhopenquery function in this article)
);
Example:
// The CPU usage of the obtained winlogon.exe process is used as an example.
// By enumerating and viewing the counting project description, you can know that the process project is a process-related project.
// By enumerating the counters and examples and viewing the instructions, we can know that the % processor time counter in the process project is about the CPU usage rate of the process.
// Finally, the Winlogon process is displayed in the counter example (indicating that the process is running)
Pdhstatus = pdhaddcounter (phquery, "// process (Winlogon) // % processor time", 0, pcounterhandle );
If (pdhstatus! = Error_success) return false;
Tip: some counters do not have instances. For example, if you want to obtain the number of seconds that the system has run since it was started, the Count item is system, the counter is system up time, and the counter instance is null, the counter path is/system up time"

6. pdhcollectquerydata: Prepare to obtain the current data
Example:
Pdhstatus = pdhcollectquerydata (phquery );
If (pdhstatus! = Error_success) return false;

7. pdhgetformattedcountervalue: Get Data
Example:
Pdhstatus = pdhgetformattedcountervalue (pcounterhandle, pdh_fmt_double,
& Dwctrtype, & fmtvalue );
If (pdhstatus! = Error_success) return false;
// Pdh_fmt_double indicates that double type data is returned. Of course, int and other types of data can be returned. Please check msdn
// Obtain the data of the next time point
/*
This blog new add:
# Define pdh_fmt_raw (DWORD) 0x00000010)
# Define pdh_fmt_ansi (DWORD) 0x00000020)
# Define pdh_fmt_unicode (DWORD) 0x00000040)
# Define pdh_fmt_long (DWORD) 0x00000100) // long
# Define pdh_fmt_double (DWORD) 0x00000200) // double
# Define pdh_fmt_large (DWORD) 0x00000400) // big number
# Define pdh_fmt_noscale (DWORD) 0x00001000) // do not apply the default scaling factor.
# Define pdh_fmt_1000 (DWORD) 0x00002000) // multify 1000
# Define pdh_fmt_nodata (DWORD) 0x00004000)
# Define pdh_fmt_nocap100 (DWORD) 0x00008000) // not reset 100 when abve 100
# Define perf_detail_costly (DWORD) 0x00010000)
# Define perf_detail_standard (DWORD) 0x0000ffff)

//-------------------------------------------------------
// The Return Value: Like abve, as fmtvalue
Typedef struct _ pdh_fmt_countervalue
{
DWORD cstatus;
Union {
Long longvalue; // type: Long
Double doublevalue; // type: double
Longlong largevalue; // type: large number, which has low and hight, two parts
Lpcstr ansistringvalue; // type: ansistring
Lpcwstr widestringvalue; // type: Unicode string
};
} Pdh_fmt_countervalue, * ppdh_fmt_countervalue;

*/
Pdhstatus = pdhcollectquerydata (phquery );
If (pdhstatus! = Error_success) return false;
Tip: pcounterhandle is the handle obtained by pdhaddcounter. Different count values can be obtained by different pcounterhandle values.

8. pdhremovecounter: Remove counter
If you do not want to obtain a counter value, you should remove it to save resources.
Example:
If (pdhremovecounter (pdhcouner )! = Error_success) return false;
This function parameter is the counter handle.

So far, if you use counters to track system information in real time, it has been explained. If you still have any questions, check msdn or
Email: wlzqin@sina.com or QQ: 8573980 contact.

3. A related API pdhgetcounterinfo is introduced in the end. This API is irrelevant to the counter usage. However, it helps you understand the path of the counter you are interested in. It can get the description of each counter Project (Chinese !)
Example:
Take obtaining the number of seconds that the system has run since its startup as an example.
Pdh_counter_info pdhcounterinfo;
DWORD dwcounterbuffsize;
// Add counter
Pdhstatus = pdhaddcounter (phquery, "// system up time", 0, pcounterhandle );
If (pdhstatus! = Error_success) return false;
// Obtain the buffer size
Pdhstatus = pdhgetcounterinfo (* pcounterhandle, true, & dwcounterbuffsize, null );
If (pdhstatus! = Error_success | pdhstatus! = Pdh_more_data) return false;
// Set the buffer
Byte * bycounterbuff = (byte *) malloc (dwcounterbuffsize );
// Obtain information
Pdhstatus = pdhgetcounterinfo (* pcounterhandle, true, & dwcounterbuffsize, (ppdh_counter_info) bycounterbuff );
If (pdhstatus! = Error_success) return false;
Pdhcounterinfo = * (ppdh_counter_info) bycounterbuff;
// Print the information
Printf (pdhcounterinfo-> szexplaintext );

The printed information is similar to: "system up time indicates the time (in seconds) that the computer has run since its last startup ). This Count value shows the difference between the start time and the current time. "
I hope this article will be helpful and have a good time.

Example code:

Int cprocessmanager: getcpuusage (tchar * processname)
{
Hquery;
Hcounter * pcounterhandle;
Pdh_status pdhstatus;
Pdh_fmt_countervalue fmtvalue;
DWORD ctrtype;
Char szpathbuffer [80] = {'/0 '};
Int retval = 0;

Pdhstatus = pdhopenquery (null, 0, & hquery); // open the query object

Pcounterhandle = (hcounter *) globalalloc (gptr, sizeof (hcounter ));

/*
// Processor (_ total) // % processor time CPU usage
// System // number of processes in the current system
// System // threads current number of system threads
// Memory // commit limit total memory size k (including virtual memory)
// Memory // committed bytes memory used K (including virtual memory)
// TCP // number of established TCP connections in the Connections active system
// Other object items can be obtained by using pdhenumobjects () and pdhenumobjectitems ()
*/

// Merge query strings

Char * process = NULL; // process counter name after processing
If (strstr (processname, ". EXE") | strstr (processname, ". EXE "))
{
// If it ends with EXE, remove the suffix
Int Len = strlen (processname)-4;
Char * TMP = new char [Len + 1];
Memcpy (TMP, processname, Len );
TMP [Len] = '/0 ';
Process = TMP;

Int num = existsamename (processname); // count

If (Num) // duplicate name
{
// If a process with the same name exists, change the current counter name to "processname # num"
// For example, msdev. EXE contains msdev, msdev #1, and msdev #2.
Process = renameex (TMP, num );
}
}
Else if (_ strcmpi (processname, "system idle Process "))
{
// If the system is idle, you can specify the counter name as idle.
Int Len = strlen ("idle ");
Char * TMP = new char [Len + 1];
Strncpy (TMP, "idle", Len );
TMP [Len] = '/0 ';
Process = TMP;
}
Else
{
// Process named System
Process = processname;
}

Sprintf (szpathbuffer, "// system // process (% s) // % C processor time", process, '% ');
Pdhstatus = pdhaddcounter (hquery, szpathbuffer, 0, pcounterhandle );
Pdhstatus = pdhcollectquerydata (hquery );
/*
# Define pdh_fmt_raw (DWORD) 0x00000010)
# Define pdh_fmt_ansi (DWORD) 0x00000020)
# Define pdh_fmt_unicode (DWORD) 0x00000040)
# Define pdh_fmt_long (DWORD) 0x00000100) // long
# Define pdh_fmt_double (DWORD) 0x00000200) // double
# Define pdh_fmt_large (DWORD) 0x00000400) // big number
# Define pdh_fmt_noscale (DWORD) 0x00001000) // do not apply the default scaling factor.
# Define pdh_fmt_1000 (DWORD) 0x00002000) // multify 1000
# Define pdh_fmt_nodata (DWORD) 0x00004000)
# Define pdh_fmt_nocap100 (DWORD) 0x00008000) // not reset 100 when abve 100
# Define perf_detail_costly (DWORD) 0x00010000)
# Define perf_detail_standard (DWORD) 0x0000ffff)
*/
Pdhstatus = pdhgetformattedcountervalue (// obtain the current counter value
* Pcounterhandle, // counter handle
Pdh_fmt_long | pdh_fmt_noscale, // format
& Ctrtype, // control type
& Fmtvalue); // Return Value

If (pdhstatus = error_success)
{
// Fmtvalue. doublevalue is the expected result
Retval = fmtvalue. longvalue; // [type: Double, long, String, large]
}
Else
{
Retval = 0;
}

Pdhstatus = pdhclosequery (hquery); // close the query handle

Return retval;
}

Discussion:
I used your program segment to get the CPU usage, but I found several problems:
Q1. obtained: fmtvalue. doublevalue: 6.4791656793412e-005 (pdhstatus =
Error_success). This is not the result of 10%, 5%, which is similar to that seen in Task Manager-performance.
A1: Expected answers

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.