MS 윈도우즈 2000 이상에서는 시스템의 성능을 모니터링 가능하도록 API 를 제공하고 있다.
Performance Monitoring [Bottom] [Top]
성능 모니터링 관련 함수 [Bottom] [Top]
1. 메모리 사용량 [Bottom] [Top]
1 DWORD GetCurrentProcessId(); 2 3 HANDLE OpenProcess( 4 DWORD dwDesiredAccess, 5 BOOL bInheritHandle, 6 DWORD dwProcessId ); 7 8 BOOL GetProcessMemoryInfo( 9 HANDLE Process, 10 PPROCESS_MEMORY_COUNTERS ppsmemCounters, 11 DWORD cb ); 12 13 BOOL CloseHandle( 14 HANDLE hObject );
2. Instance 이름 [Bottom] [Top]
1 HANDLE OpenProcess( 2 DWORD dwDesiredAccess, 3 BOOL bInheritHandle, 4 DWORD dwProcessId ); 5 6 BOOL EnumProcessModules( 7 HANDLE hProcess, 8 HMODULE * lphModule, 9 DWORD cb, 10 LPDWORD lpcbNeeded ); 11 12 DWORD GetModuleBaseName( 13 HANDLE hProcess, 14 HMODULE hModule, 15 LPTSTR lpBaseName, 16 DWORD nSize ); 17 18 BOOL CloseHandle( 19 HANDLE hObject );
3. CPU 사용량 [Bottom] [Top]
1 // STEP 1: Creating a Query 2 PDH_STATUS PdhOpenQuery( 3 LPCTSTR szDataSource, 4 DWORD_PTR dwUserData, 5 PDH_HQUERY * phQuery ); 6 7 // STEP 2: Adding Counters to a Query 8 PDH_STATUS PdhMakeCounterPath( 9 PDH_COUNTER_PATH_ELEMENTS * pCounterPathElements, 10 LPTSTR szFullPathBuffer, 11 LPDWORD pcchBufferSize, 12 DWORD dwFlags ); 13 14 PDH_STATUS PdhRemoveCounter( 15 PDH_HCOUNTER hCounter ); 16 17 PDH_STATUS PdhAddCounter( 18 PDH_HQUERY hQuery, 19 LPCTSTR szFullCounterPath, 20 DWORD_PTR dwUserData, 21 PDH_HCOUNTER * phCounter ); 22 23 // STEP 3: Collecting Performance Data 24 PDH_STATUS PdhCollectQueryData( 25 PDH_HQUERY hQuery ); 26 27 // STEP 4: Process the performance data 28 PDH_STATUS PdhGetFormattedCounterValue( 29 PDH_HCOUNTER hCounter, 30 DWORD dwFormat, 31 LPDWORD lpdwType, 32 PPDH_FMT_COUNTERVALUE pValue ); 33 34 // STEP 5: Closing the Query 35 PDH_STATUS PdhCloseQuery( 36 PDH_HQUERY hQuery );
CPU 와 메모리 사용량 측정 클래스 [Bottom] [Top]
1 // ProcessMonitor.h : CProcessMonitor 클래스 선언 2 // 3 4 #pragma once 5 6 7 // 클래스 선언 8 class CProcessMonitor 9 { 10 // 생성자/소멸자 11 public: 12 CProcessMonitor(); 13 virtual ~CProcessMonitor(); 14 15 // 멤버 함수 16 public: 17 HRESULT Create(); 18 void Close(); 19 20 float GetCpuUsage(); 21 DWORD GetMemoryUsage(); 22 23 protected: 24 HRESULT CreateCpuUsageCounter(); 25 void CloseCpuUsageCounter(); 26 27 // 멤버 변수 28 protected: 29 HANDLE m_hProcess; 30 TCHAR m_szProcessName[ MAX_PATH ]; 31 32 HQUERY m_hCpuUsageQuery; 33 HCOUNTER m_hCpuUsageCounter; 34 };
1 // ProcessMonitor.cpp : CProcessMonitor 클래스 구현 2 // 3 4 #include "StdAfx.h" 5 #include "ProcessMonitor.h" 6 7 8 // 생성자/소멸자 구현 9 CProcessMonitor::CProcessMonitor() 10 : m_hProcess( NULL ) 11 , m_hCpuUsageQuery( NULL ) 12 , m_hCpuUsageCounter( NULL ) 13 { 14 } 15 16 CProcessMonitor::~CProcessMonitor() 17 { 18 Close(); 19 } 20 21 // 멤버 함수 구현 22 HRESULT CProcessMonitor::Create() 23 { 24 // Process 정보 열기 25 DWORD dwProcessID = GetCurrentProcessId(); 26 27 m_hProcess = OpenProcess( 28 PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 29 FALSE, 30 dwProcessID ); 31 32 if( NULL == m_hProcess ) 33 { 34 return E_FAIL; 35 } 36 37 // Process Instance 정보 찾음 38 HMODULE hModule; 39 DWORD dwNeeded; 40 41 if( FALSE == EnumProcessModules( m_hProcess, &hModule, sizeof( hModule ), &dwNeeded ) ) 42 { 43 // TODO: 에러 처리 44 // GetLastError() 45 46 return E_FAIL; 47 } 48 49 if( 0 == GetModuleBaseName( m_hProcess, hModule, m_szProcessName, sizeof( m_szProcessName ) / sizeof( TCHAR ) ) ) 50 { 51 // TODO: 에러 처리 52 // GetLastError() 53 54 return E_FAIL; 55 } 56 57 // Process 확장자 제거 58 TCHAR * pPeriod = _tcschr( m_szProcessName, '.' ); 59 60 if( NULL != pPeriod ) 61 { 62 *pPeriod = _T( '\0' ); 63 } 64 65 // CPU 사용량 카운터 생성 66 if( FAILED( CreateCpuUsageCounter() ) ) 67 { 68 return E_FAIL; 69 } 70 71 return S_OK; 72 } 73 74 void CProcessMonitor::Close() 75 { 76 if( NULL != m_hProcess ) 77 { 78 // CPU 사용량 카운터 제거 79 CloseCpuUsageCounter(); 80 81 // Process 정보 닫음 82 CloseHandle( m_hProcess ); 83 84 m_hProcess = NULL; 85 } 86 } 87 88 float CProcessMonitor::GetCpuUsage() 89 { 90 // CPU 사용량 정보 수집 91 PDH_STATUS pdhStatus = PdhCollectQueryData( m_hCpuUsageQuery ); 92 93 if( ERROR_SUCCESS != pdhStatus ) 94 { 95 // TODO: 에러 처리 96 // pdhStatus ==> ErrorCode 97 98 return -1; 99 } 100 101 // CPU 사용량 정보 처리 102 PDH_FMT_COUNTERVALUE fmtValue; 103 104 pdhStatus = PdhGetFormattedCounterValue( m_hCpuUsageCounter, PDH_FMT_DOUBLE, NULL, &fmtValue ); 105 106 if( ERROR_SUCCESS != pdhStatus ) 107 { 108 // TODO: 에러 처리 109 // pdhStatus ==> ErrorCode 110 111 return -1; 112 } 113 114 return static_cast< float >( fmtValue.doubleValue ); 115 } 116 117 DWORD CProcessMonitor::GetMemoryUsage() 118 { 119 // Memory 사용량 정보 처리 120 PROCESS_MEMORY_COUNTERS pmc; 121 122 if( 0 == GetProcessMemoryInfo( m_hProcess, &pmc, sizeof( pmc ) ) ) 123 { 124 // TODO: 에러 처리 125 // GetLastError() 126 127 return -1; 128 } 129 130 return pmc.WorkingSetSize; 131 } 132 133 HRESULT CProcessMonitor::CreateCpuUsageCounter() 134 { 135 // PDH Query 생성 136 PDH_STATUS pdhStatus = PdhOpenQuery( NULL, 0, &m_hCpuUsageQuery ); 137 138 if( ERROR_SUCCESS != pdhStatus ) 139 { 140 // TODO: 에러 처리 141 // pdhStatus ==> ErrorCode 142 143 return E_FAIL; 144 } 145 146 // CPU 사용량 Query 문자열 147 TCHAR szCounterPath[ MAX_PATH ]; 148 149 _stprintf_s( szCounterPath, _T( "\\Process(%s)\\%% Processor Time" ), m_szProcessName ); 150 151 // CPU 사용량 카운터 추가 152 pdhStatus = PdhAddCounter( m_hCpuUsageQuery, szCounterPath, 0, &m_hCpuUsageCounter ); 153 154 if( ERROR_SUCCESS != pdhStatus ) 155 { 156 // TODO: 에러 처리 157 // pdhStatus ==> ErrorCode 158 159 return E_FAIL; 160 } 161 162 return S_OK; 163 } 164 165 void CProcessMonitor::CloseCpuUsageCounter() 166 { 167 // CPU 사용량 카운터 제거 168 PDH_STATUS pdhStatus = PdhCloseQuery( m_hCpuUsageQuery ); 169 }
1. 사용법 [Bottom] [Top]
1 #include <windows.h> 2 #include <psapi.h> 3 #include <pdh.h> 4 5 #pragma comment( lib, "psapi" ) 6 #pragma comment( lib, "pdh" ) 7 8 #include "ProcessMonitor.h" 9 10 11 int main() 12 { 13 CProcessMonitor monitor; 14 15 monitor.Create(); 16 17 ... 18 19 printf( "CPU Usage : %.3f%%\n", monitor.GetCpuUsage() ); 20 printf( "Memory Usage : %dKB\n", monitor.GetMemoryUsage () / 1024 ); 21 22 return 0; 23 }
