사용자 삽입 이미지

#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 정훈승