'cpu사용률'에 해당되는 글 2건

  1. 2009.04.12 cpu사용률, 메모리 과부하 프로그램 죽이기 4
  2. 2009.04.03 현재 CPU 사용률 6
사용자 삽입 이미지

#include <windows.h> // Windows API 함수를 위한 헤더파일
#include <tlhelp32.h> // 프로세스정보를 읽기 위한 헤더파일
#include <psapi.h> // enumprocess를 위한 헤더파일
#include <conio.h> // kbhit(아무키나 누르면 종료)를 위한 헤더파일
#include <ctime> // 시간출력을 위한 헤더파일
#include <iostream>
using namespace std;
static int signal; // abnormal인지 normal인지 구분, 매 삽입시마다 초기화되어야 하므로 static으로 선언
int count=0, cputime=0, pid;
SYSTEMTIME pkTimeProcess[1024]; // 이전 kernel time을 위한 배열
SYSTEMTIME puTimeProcess[1024]; // 이전 user time을 위한 배열
SYSTEMTIME ckTimeProcess[1024]; // 현재 kernel time을 위한 배열
SYSTEMTIME cuTimeProcess[1024]; // 현재 user time을 위한 배열
int previousCPU(DWORD processID, int i); // 이전 cpu정보를 얻음
int currentCPU(DWORD processID, int i); // 현재 cpu정보를 얻음
void tmPROCESS(DWORD processID); // 프로세스를 죽이는 함수
int kill(DWORD processID, int i); // 죽이는 조건
void main( )
{
 while(!_kbhit())
 {
  time_t lc;
  time(&lc);
  struct tm *today; // 시간 구조체 선언
  DWORD aProcesses[1024], cbNeeded, cProcesses; // 프로세스 리스트를 위한 변수
  unsigned int i;
  if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) return; // EnumProcesses가 아니면 리턴
 
  cProcesses = cbNeeded / sizeof(DWORD); // 프로세스 리스트 저장
 
  for (i=0; i<cProcesses; i++) previousCPU(aProcesses[i], i);
  Sleep(1000); // 1000 = 1초
  for (i=0; i<cProcesses; i++) currentCPU(aProcesses[i], i);
  for (i=0; i<cProcesses; i++) kill(aProcesses[i], i);
  cout << localtime(&lc)->tm_year+1900 << "."; // 1900을 더해야 서기년도가 됨
  cout << localtime(&lc)->tm_mon+1 << "."; // 1월이 0이기 때문에 +1을 해야 됨
  cout << localtime(&lc)->tm_mday << " " << localtime(&lc)->tm_hour << ":" << localtime(&lc)->tm_min << ":" << localtime(&lc)->tm_sec;
  cout << ", " << "Current Process : " << i;
  if(signal == 0) cout << " - Normal\n";
  else cout << " - Abnormal\n"; // signal이 0이면 노말, 아니면 앱노말
 }
}
int previousCPU(DWORD processID, int i)
{
 FILETIME createTime1;
 FILETIME exitTime1;
 FILETIME kernelTimeProcess1;
 FILETIME userTimeProcess1;
 HANDLE hProcess;
 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID ); // 핸들 오픈
 if (NULL == hProcess) return 0; // 핸들이 프로세스를 갖고 있지 않다면 리턴
       
 GetProcessTimes( hProcess , &createTime1, &exitTime1, &kernelTimeProcess1, &userTimeProcess1); // cputime 계산
 FileTimeToSystemTime(&kernelTimeProcess1, &pkTimeProcess[i]); // system time 저장
 FileTimeToSystemTime(&userTimeProcess1, &puTimeProcess[i]); // system time 저장
}
int currentCPU(DWORD processID, int i)
{
 FILETIME createTime2;
 FILETIME exitTime2;
 FILETIME kernelTimeProcess2;
 FILETIME userTimeProcess2;
 HANDLE hProcess;
 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID ); // 핸들 오픈
 if (NULL == hProcess) return 0; // 핸들이 프로세스를 갖고 있지 않다면 리턴
       
 GetProcessTimes( hProcess , &createTime2, &exitTime2, &kernelTimeProcess2, &userTimeProcess2); // cputime 계산
 FileTimeToSystemTime(&kernelTimeProcess2, &ckTimeProcess[i]); // system time 저장
 FileTimeToSystemTime(&userTimeProcess2, &cuTimeProcess[i]); // system time 저장
}
void tmPROCESS(DWORD processID)
{
 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID );
 TerminateProcess(hProcess, NULL); // 과부하 프로세스 죽이는 함수
}
int kill(DWORD processID, int i)
{
 TCHAR szProcessName[MAX_PATH] = TEXT(""); // 파일경로 초기화
 HMODULE hMod; // 모듈정보를 얻기 위한 선언
 DWORD cbNeeded; // 모듈정보를 얻기 위한 선언
 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID ); // 핸들 오픈
 PROCESS_MEMORY_COUNTERS pmc; // 메모리저장을 위한 선언
 int cputime=0;
 if (NULL == hProcess) return 0; // 핸들이 프로세스를 갖고 있지 않다면 리턴
       
 if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
 GetModuleFileNameEx(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR));
 cputime = // cpu사용률 계산
    (((((ckTimeProcess[i].wSecond*1000+ckTimeProcess[i].wMilliseconds)
   - (pkTimeProcess[i].wSecond*1000+pkTimeProcess[i].wMilliseconds))
   + (cuTimeProcess[i].wSecond*1000+cuTimeProcess[i].wMilliseconds )
   - (puTimeProcess[i].wSecond*1000+puTimeProcess[i].wMilliseconds)) /1000)*100);
 GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)); // 메모리 정보를 얻음
 if((pmc.WorkingSetSize/(1024) + pmc.PagefileUsage/(1024)) >= 200000) // 메모리 과부하 종료조건
 {
  tmPROCESS(processID);
  cout << "Memory overloaded process is terminated.\n";
  cout << "PID : " << processID << " CPU : " << cputime;
  cout << " MEMORY : " << (pmc.WorkingSetSize/(1024) + pmc.PagefileUsage/(1024)) << "\n";
  _tprintf(TEXT("%s \n"), szProcessName); // 현재 파일경로
  signal = 1; // 0이 아니기 때문에 앱노말
 }
 else if(cputime >= 90) // cpu사용률 과부하 종료조건
 {
  tmPROCESS(processID);
  cout << "CPU overloaded process is terminated.\n";
  cout << "PID : " << processID << " CPU : " << cputime;
  cout << " MEMORY : " << (pmc.WorkingSetSize/(1024) + pmc.PagefileUsage/(1024)) << "\n";
  _tprintf(TEXT("%s \n"), szProcessName); // 현재 파일경로
  signal = 1; // 0이 아니기 때문에 앱노말
 }
 CloseHandle(hProcess); // 핸들 종료
}

매 초마다 cpu사용률과 메모리가 과부하 되는지 체크하는 프로그램입니다.
cpu사용률 또는 메모리가 과부하 되면 자동으로 그 프로세스를 죽여버립니다.

교수님께서 이 숙제를 내주시면서 말씀하셨습니다.
"하루 이틀 밤새는 걸로는 안될꺼에요"

그렇습니다. 이번 프로그래밍을 어디 참조 안하고 하루안에 푼다면 진짜 고수겠죠..
하지만 저를 비롯해서, 수많은 학생들이 고수가 아니기에...ㅠㅠ

깔끔하게 정리된 이 소스를 보고
어두운 감옥에서 한줄기 희망의 빛을 보시길 바랍니다 -_- ㅎㅎㅎㅎ


그리고 제 블로그 어딘가에 프로그래밍 숙제 도와드린단 말이 있나요?
있다면 그건,
고려대 과학기술대학 학생에 한하는 말입니다...
다른학교 숙제까지 해줄 정도로 제가 시간이 많지가 않아요 ㅠㅠ

고려대 과학기술대학 학생이 프로그래밍 숙제하다가 졸라 후달릴 경우
저에게 이메일 주시면 제가 도움을 줄 수도 있습니다. 
Posted by 정훈승
사용자 삽입 이미지


#define _WIN32_WINNT 0x0501 // GetSystemTimes를 사용하기 위한 정의
#include <iostream>
#include <ctime> // 시간출력을 위한 헤더파일
#include <windows.h> // Windows API 함수를 위한 헤더파일
#include <conio.h> // kbhit(아무키나 누르면 종료)를 위한 헤더파일
using namespace std;
__int64 getCPU();
void Print_Current_Time();
int main()
{
 int jhs[9999], mm[10]; // jhs는 초단위 데이터를 위한 배열, mm을 버블정렬에 쓰일 배열
 int a, b, temp; // 버블정렬을 위한 인수
 for(int i=0; !_kbhit(); i++)
 {
  cout << "\n(" << i << ") ";// 1초마다 번호 매김
  Print_Current_Time();
  jhs[i]=getCPU(); // 현재 cpu사용률을 배열에 저장
  cout <<"[CPU Load: "<< jhs[i] <<"]";
 
  if(i>=9) // 10번째부터 최소값, 평균값, 최대값 계산
  {
   mm[0] = jhs[i-9];
   mm[1] = jhs[i-8];
   mm[2] = jhs[i-7];
   mm[3] = jhs[i-6];
   mm[4] = jhs[i-5];
   mm[5] = jhs[i-4];
   mm[6] = jhs[i-3];
   mm[7] = jhs[i-2];
   mm[8] = jhs[i-1];
   mm[9] = jhs[i];
   for(a=1; a<10; a++) // 버블정렬
   {
    for(b=10-1; b>=a; b--)
    {
     if(mm[b-1] > mm[b])
     {
      temp = mm[b-1];
      mm[b-1] = mm[b];
      mm[b] = temp;
     }
    }
   }
   cout << " - [Min : " << mm[0] << "]"; // 최소값
   cout << " - [Ave : " << (mm[0]+mm[1]+mm[2]+mm[3]+mm[4]+mm[5]+mm[6]+mm[7]+mm[8]+mm[9])/10 << "]";
   cout << " - [Max : " << mm[9] << "]"; // 최대값
  }
 }
 return 0;
}

// ********** getCPU 함수는 외국사이트에서 참조했습니당 **********************
__int64 getCPU(void) {
 FILETIME idleTime;   // ┐
 FILETIME kernelTime; // │ GetSystemTimes's parameter
 FILETIME userTime;   // ┘
 GetSystemTimes(&idleTime, &kernelTime, &userTime);
 DWORD kernel1_high = kernelTime.dwHighDateTime;  // In first kernel's HighDataTime
 DWORD kernel1_low = kernelTime.dwLowDateTime;    // In first kernel's LowDataTime
 DWORD user1_high = userTime.dwHighDateTime;      // In first user's HighDataTime
 DWORD user1_low = userTime.dwLowDateTime;        // In first user's LowDataTime
 DWORD idle1_high = idleTime.dwHighDateTime;      // In first idle's HighDataTime
 DWORD idle1_low = idleTime.dwLowDateTime;        // In first idle's LowDataTime
 DWORD high1 = kernel1_high + user1_high + idle1_high; // Add each first HighTime
 Sleep(1000); // 1000 is 1초
 GetSystemTimes(&idleTime, &kernelTime, &userTime);
 DWORD kernel2_high = kernelTime.dwHighDateTime;  // In second kernel's HighDataTime
 DWORD kernel2_low = kernelTime.dwLowDateTime;    // In second kernel's LowDataTime
 DWORD user2_high = userTime.dwHighDateTime;      // In second user's HighDataTime
 DWORD user2_low = userTime.dwLowDateTime;        // In second user's LowDataTime
 DWORD idle2_high = idleTime.dwHighDateTime;      // In second idle's HighDataTime
 DWORD idle2_low = idleTime.dwLowDateTime;        // In second idle's LowDataTime
 DWORD high2 = kernel2_high + user2_high + idle2_high; // Add each second HighTime
 DWORD high = high2 - high1; // differ to first HighTime and second HighTime
 __int64 kernel = kernel2_low - kernel1_low; // In used kernel time in 1 sec
 __int64 user = user2_low - user1_low;       // In used user time in 1 sec
 __int64 idle = idle2_low - idle1_low;       // in used idle time in 1 sec
 
 if(high) { // if high != 0
  if(high==1) { // many times tested -> high no more than 3
   kernel = (kernel/10)+10000000000; // ┐ Effection of "high & low" ex) high=2, low=100 -> 210 (& : connection operator)
   user = (user/10)+10000000000;     // │ Why 210 not 2100? : Because only compare to 3 values(kernel,user,idle) for get CPU rate
   idle = (idle/10)+10000000000;     // ┘  (ex> 100/210 = 1000/2100)
  }
  if(high==2) {
   kernel = (kernel/10)+20000000000;
   user = (user/10)+20000000000;
   idle = (idle/10)+20000000000;
  }
 }
 
 // get CPU rate
 // Why __int64?
 // Because DWORD < __int64 (compare to data size) / DWORD + DWORD -> sometimes overflow occurrence
 __int64 delta = ((user+kernel)-idle) * 100 / (user+kernel);
 return delta;
}

void Print_Current_Time()
{
 struct tm *st;
 time_t t;
 t = time(NULL); // t에 초단위의 시간이 저장됨
 st = localtime(&t); // 초단위의 시간을 구조체로 바꿈
 cout << st->tm_year+1900 << "."; // 1900을 더해야 서기년도가 표시됨
 cout << st->tm_mon+1 << "."; // 1월=0, 2월=1 이기 때문에 +1을 해야됨
 cout << st->tm_mday << " ";
 cout << st->tm_hour << ":";
 cout << st->tm_min << ":";
 cout << st->tm_sec << " - ";
}


매 초마다 현재 CPU 사용률입니다.
기본적으로 무한루프이고, 아무키나 누르면 빠져나옵니다.

10번째 출력부터 최근 10개의 최소값, 평균값, 최대값을 출력합니다.


p.s
고려대학교 컴퓨터정보학과, 운영체제 듣고 있는 학생들 졸라 똥줄 타죠...
이번 숙제는, 제가 지능형웹서비스 숙제하느라 뒤질뻔해서 시간이 너무많이 부족했습니다...
그래서 아예 시작을 늦게하느라
마감기한을 넘기지 않으려고 시간없어서 부랴부랴 main문 안에다가 대충 처박았습니다.

더 좋은 프로그램을 만들고 싶다면
각 기능들(버블소트 등...)을 함수로 따로 만들면 좋을 것 같습니다.
그리고 버블소트가 가장 간단해서 버블소트로 했는데, 퀵소트 같은것들로 바꿔도 좋은 방법이겠지요



마지막으로 다른 학생들에게 이 소스가 똥줄타는 가슴에 촉촉하게 스며드는 단비가 되길 바랍니다
Posted by 정훈승