Sunday, June 24, 2012

C++ Get CPU and Memory Utilisation

Write and compile the application

  1. While you can get Memory status fairly easlily with GlobalMemoryStatusEx, there is no equivalent function for CPU. Therefore you have to use PDH Performance Counter Interface to get CPU utilisation. Write the application and save is as check.cpp.

    Also note that CPU is a difference between two PdhCollectQueryData calls, so if you call this once and try to get PdhGetFormattedCounterValue you will get an error.

     1. #include <iostream>
     2. #include <windows.h>
     3. #include <stdio.h>
     4. #include <pdh.h>
     5. #include <pdhmsg.h>
     6. 
     7. #define KB 1024
     8. void main(int argc, char *argv[]){
     9. 
    10.     PDH_HQUERY hquery;
    11.     PDH_HCOUNTER hcountercpu;
    12.     PDH_HCOUNTER hcounterram;
    13.     PDH_STATUS status;
    14.     LPSTR pMessage;
    15.     PDH_FMT_COUNTERVALUE countervalcpu;
    16.     PDH_FMT_COUNTERVALUE countervalram;
    17.     MEMORYSTATUSEX memstat;
    18.     
    19.     memstat.dwLength = sizeof (memstat);
    20. 
    21.     if((status=PdhOpenQuery(NULL, 0, &hquery))!=ERROR_SUCCESS){
    22.         printf("PdhOpenQuery %lx\n", status);    
    23.         goto END;
    24.     }
    25. 
    26.     if((status=PdhAddCounter(hquery,
    27.                             "\\Processor(_Total)\\% Processor Time",
    28.                             0, 
    29.                             &hcountercpu))!=ERROR_SUCCESS){
    30.         printf("PdhAddCounter (cpu) %lx\n", status);    
    31.         goto END;
    32.     }
    33.     if((status=PdhAddCounter(hquery,
    34.                             "\\Memory\\Available Bytes",
    35.                             0, 
    36.                             &hcounterram))!=ERROR_SUCCESS){
    37.         printf("PdhAddCounter (ram) %lx\n", status);    
    38.         goto END;
    39.     }
    40.     
    41.     /*Start outside the loop as CPU requires difference 
    42.     between two PdhCollectQueryData s*/
    43.     if((status=PdhCollectQueryData(hquery))!=ERROR_SUCCESS){
    44.         printf("PdhCollectQueryData %lx\n", status);    
    45.         goto END;
    46.     }
    47. 
    48.     while(true){
    49. 
    50.         if((status=PdhCollectQueryData(hquery))!=ERROR_SUCCESS){
    51.             printf("PdhCollectQueryData %lx\n", status);    
    52.             goto END;
    53.         }
    54.         if(GlobalMemoryStatusEx(&memstat)==0){
    55.             printf("GlobalMemoryStatusEx %d\n", GetLastError());
    56.             goto END;
    57.         }
    58. 
    59.         if((status=PdhGetFormattedCounterValue(hcountercpu, 
    60.                                                 PDH_FMT_LONG, 
    61.                                                 0, 
    62.                                                 &countervalcpu))!=ERROR_SUCCESS){
    63.             printf("PdhGetFormattedCounterValue(cpu) %lx\n", status);    
    64.             goto END;
    65.         }
    66.         if((status=PdhGetFormattedCounterValue(hcounterram, 
    67.                                                 PDH_FMT_LONG, 
    68.                                                 0, 
    69.                                                 &countervalram))!=ERROR_SUCCESS){
    70.             printf("PdhGetFormattedCounterValue(ram) %lx\n", status);    
    71.             goto END;
    72.         }
    73.         printf("cpu %3d%% \tmem %3d%% \tavail (%d mb)\n", 
    74.             countervalcpu.longValue, 
    75.             memstat.dwMemoryLoad, 
    76.             countervalram.longValue/(KB*KB));
    77. 
    78.         Sleep(1000);
    79. 
    80.     }
    81. END:
    82.     ;
    83. }

  2. Open a prompt to the working directory and compile the code using the windows cl.exe compiler. You just need to include the pdh.lib.

    ..workspace\PerfCounter>cl check.cpp pdf.lib

  3. Now run the program in the command prompt. You should see the cpu and memory snapshot displayed every second.

No comments:

Post a Comment