'운영체제'에 해당되는 글 6건

  1. 2009.06.14 Dining Philosopher
  2. 2009.05.21 Process Scheduling 13
  3. 2009.05.01 두 프로그램 간 파이프 통신 6
  4. 2009.04.12 cpu사용률, 메모리 과부하 프로그램 죽이기 4
  5. 2009.04.03 현재 CPU 사용률 6
  6. 2009.03.23 실행중인 프로세스 개수 1
고려대 컴퓨터정보학과
Operating System Programming Assignment 마지막~!

Dining Philosopher

사실 내가 백프로 짠 쏘스도 아니고
마지막이기도 하고
걍 소스코드 전부다 공개


 
dp.h 소스코드
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <tchar.h>
#include <windows.h>

#ifndef __Dining_Philosopher_h
#define __Dining_Philosopher_h

#define MAXLIST  256
#define MAXNAME  32

class Dining_Philosopher
{
private:
 int    m_id;
public:
 Dining_Philosopher(int id);
 ~Dining_Philosopher();
 void print();
 void eat();
 void think();
protected:
};

#endif


dp.cpp 소스코드
#include "dp.h"
Dining_Philosopher::Dining_Philosopher(int id)
{
 memset(this, 0, sizeof(Dining_Philosopher) );
 srand( (unsigned int)time(NULL) );
 this->m_id = id;
 this->print();
}

Dining_Philosopher::~Dining_Philosopher(void)
{
 
}

void Dining_Philosopher::print()
{
 printf("philosopher DI: %3d\n", m_id);
}

void Dining_Philosopher::eat()
{
 int eat_time = 1 + rand() % 10;
 printf("[%1d:", m_id);
 Sleep( eat_time );
 printf(":%1d]\n", m_id);
}

void Dining_Philosopher::think()
{
 int think_time = 1 + rand() % 10;
 Sleep( think_time );
}


jhs.cpp 소스코드 (메인파일)
#include "dp.h"
#include <iostream>
using namespace std;
typedef struct Man // Sitdown Man Information Struct
{
 int id;
 Dining_Philosopher *dp;
 HANDLE left,right;
} Man;

DWORD WINAPI WriteToDatabase( LPVOID );
void main() // 5 is Maz Size
{
 HANDLE ghMutex[5];
 HANDLE aThread[5];
 DWORD ThreadID;
 struct Man DP[5];
 int i,j,temp;
 bool random_check; // If Event Random is coming, Same Number is interception
 
 for(i=0;i<5;i++) // Create a mutex with no initial owner
 {
  ghMutex[i] = CreateMutex(
   NULL,              // default security attributes
   FALSE,             // initially not owned
   NULL);             // unnamed mutex
  if (ghMutex == NULL)
  {
   printf("CreateMutex error: %d\n", GetLastError());
   return;
  }
 }
 // Setting each Man Number, Setting Left, Right
 srand( (unsigned int)time(NULL) );
 for(i=0;i<5;i++)
 {
  while(1)
  {
   temp=rand()%5+1;
   random_check=true;
   for(j=0;j<5;j++)
   {
    if(temp==DP[j].id) random_check=false;
   }
   if(random_check==true)
   {
    DP[i].id=temp;
    DP[i].dp= new Dining_Philosopher(temp);
    DP[i].right = ghMutex[i];
    if(i==0) DP[i].left=ghMutex[4]; 
    else DP[i].left=ghMutex[i-1];
    break;
   }
  }
 }
    // Create worker threads
 for( i=0; i < 5; i++ )
 {
  aThread[i] = CreateThread(
     NULL,       // default security attributes
     0,          // default stack size
     (LPTHREAD_START_ROUTINE) WriteToDatabase,
     &DP[i],       // thread function arguments
     0,          // default creation flags
     &ThreadID); // receive thread identifier
  if( aThread[i] == NULL ){
  printf("CreateThread error: %d\n", GetLastError());
  return;
  }
 }
    // Wait for all threads to terminate
 WaitForMultipleObjects(5, aThread, TRUE, INFINITE);
    // Close thread and mutex handles
 for( i=0; i < 5; i++ ) CloseHandle(aThread[i]);
    for( i=0; i < 5; i++ ) CloseHandle(ghMutex[i]);
}
 
DWORD WINAPI WriteToDatabase( LPVOID lpParam  )
{
 Man *temp = (Man *)lpParam;
 DWORD dwCount=0, LWait,RWait;
 //If Eating Counting Numbers are 5, End
 while( dwCount < 5 )
 {
  // Waiting eat
  temp->dp->think();
 
  // Waiting Part. Ror Left and Right Catching
  LWait=WaitForSingleObject(temp->left,INFINITE);
  RWait=WaitForSingleObject(temp->right,INFINITE);
  switch(LWait & RWait)
  {
   // If left and right empty
   case WAIT_OBJECT_0: __try
   {
    temp->dp->eat();
    dwCount++;
   }
   __finally
   {
    ReleaseMutex(temp->left);
    ReleaseMutex(temp->right);
   }
   break;
 
   case WAIT_ABANDONED:
   return FALSE;
  }
 }
 return TRUE;
}


이건 실행화면

사용자 삽입 이미지
Posted by 정훈승
제대로 똥줄타는 숙제였다.
문제는 SJF알고리즘을 사용해서 프로세스 스케줄링 하는거다.
결론부터 말하자면 정답을 못구했다.
왜냐면 나 스스로 SJF알고리즘을 제대로 이해하지 못했다 ㅠㅠ

왠만한 학생들은 정말 제대로 똥줄탈 것이다.
제대로 똥줄타는 숙제이므로 소스는 공개하지 않겠다.

고려대 컴퓨터정보학과 학생중 진짜 진정으로 진심으로 똥줄이 팍팍 탄다면!!!
과기대에서 저를 만난다면!!! 커피한잔 사주세용^^ (꽁짜는 없씀)


사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
Posted by 정훈승
이번 꺼는 두 프로그램 간 파이프를 이용한 통신입니다.
클라이언트 프로그램에서 정렬되지 않은 숫자가 내용인 텍스트파일을 읽으면
서버 프로그램에서 그 텍스트파일 안에 있는 숫자들을 정렬합니다.
그리고 다시 클라이언트 프로그램에 정렬된 결과를 출력합니다.

두개의 프로젝트를 생성해야겠지요...
클라이언트와 서버

이번 과제 고생을 좀 해서....소스코드는 공개하지 않습니다ㅠㅠ
진짜 진짜 완전 똥줄타는 사람은 이메일보내시던지, 학교에서 나 만나면 음료수 사주시던지...

사용자 삽입 이미지


사용자 삽입 이미지


사용자 삽입 이미지


사용자 삽입 이미지


사용자 삽입 이미지


사용자 삽입 이미지


사용자 삽입 이미지


사용자 삽입 이미지


사용자 삽입 이미지

 

assignment-04.zip

하도 소스파일 보내달라고 징징거리는 후배들때문에 이렇게 소스코드 공개합니다.

모름지기 싸나이라면 해도해도 안되면 그때 퍼가시길 바랍니다.

Posted by 정훈승
사용자 삽입 이미지

#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 정훈승
사용자 삽입 이미지

 
// Program Name : PROCESS COUNTER
// Written by Hoon-seung Jeong

// Consultation http://support.microsoft.com/kb/175030/ko


#include <iostream>
#include <windows.h>
// For Windows API function
#include <time.h>
// For time of day
#include <tlhelp32.h>
// For process count of Windows XP
using namespace std;
void Process_Count();
int main()
{
    while(1)
    {
        Process_Count();
    }
    return 0;
}
void Process_Count()
{
    int number=0;
// Initialization 0
    time_t now;
// Declare time struct
    now = time(NULL); // Time function
    HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // This function has system information
    if(snap) // Excution snapshat handle
    {
        BOOL p_Count;
// For count process
        PROCESSENTRY32 p_Entry; // Declare process struct
        p_Entry.dwSize = sizeof(PROCESSENTRY32); // A Function of PROCESSENTRY32
        p_Count = Process32First(snap, &p_Entry); // Search a executing process
        while(p_Count)
        {
            p_Count = Process32Next(snap, &p_Entry);
// Repeat to search executing process
            number++;
// Increase number of executing process
        }
        CloseHandle(snap); // Close snapshot handle
    }
    cout << asctime(localtime(&now)); // Print time of day
    cout << "\tNumber of executing process : " << number << "\n"; // Print number of executing process
    Sleep(1000);
// 1000 is 1 second
}

프로그램 제목 : Process Counter

윈도우상에서 컨트롤+알트+델 누르면
윈도우즈 작업관리자가 뜨는데
왼쪽 하단에 현재 실행중인 프로세스 개수가 뜬다.

그걸 콘솔모드(도스모드) 프로그램으로 해본 것...
Posted by 정훈승