CAFE

☆ 프로그래밍 팁

성능 모니터링, Win32 ver

작성자만진씨.|작성시간08.07.28|조회수1,003 목록 댓글 0

 

출처 :

 

http://www.viper.pe.kr/cgi-bin/moin.cgi/%EC%84%B1%EB%8A%A5_%EB%AA%A8%EB%8B%88%ED%84%B0%EB%A7%81?highlight=%28CategoryWin32%29

 

 

 

 

MS 윈도우즈 2000 이상에서는 시스템의 성능을 모니터링 가능하도록 API 를 제공하고 있다.

Performance Monitoring

성능 모니터링 관련 함수

1. 메모리 사용량

function isnumbered(obj) { return obj.childNodes.length && obj.firstChild.childNodes.length && obj.firstChild.firstChild.className == 'LineNumber'; } function nformat(num,chrs,add) { var nlen = Math.max(0,chrs-(''+num).length), res = ''; while (nlen>0) { res += ' '; nlen-- } return res+num+add; } function addnumber(did, nstart, nstep) { var c = document.getElementById(did), l = c.firstChild, n = 1; if (!isnumbered(c)) if (typeof nstart == 'undefined') nstart = 1; if (typeof nstep == 'undefined') nstep = 1; n = nstart; while (l != null) { if (l.tagName == 'SPAN') { var s = document.createElement('SPAN'); s.className = 'LineNumber' s.appendChild(document.createTextNode(nformat(n,4,' '))); n += nstep; if (l.childNodes.length) l.insertBefore(s, l.firstChild) else l.appendChild(s) } l = l.nextSibling; } return false; } function remnumber(did) { var c = document.getElementById(did), l = c.firstChild; if (isnumbered(c)) while (l != null) { if (l.tagName == 'SPAN' && l.firstChild.className == 'LineNumber') l.removeChild(l.firstChild); l = l.nextSibling; } return false; } function togglenumber(did, nstart, nstep) { var c = document.getElementById(did); if (isnumbered(c)) { remnumber(did); } else { addnumber(did,nstart,nstep); } return false; } document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
   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 이름

document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
   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 사용량

document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
   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 와 메모리 사용량 측정 클래스

document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
   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 };

document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
   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.doubleVal‎ue );
 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. 사용법

document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
   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 }


 

다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼