Queue를 이용한 스케쥴러 시뮬레이션 [C++]

안녕하세요. 언제나 휴일에 언휴예요.

이번 실습은 Queue를 이용한 스케쥴러 시뮬레이션입니다.

스케쥴러는 운영체제의 핵심 개체로 누가 CPU를 점유하여 사용할 것인지를 판단하는 역할을 수행합니다.

여기에서는 대기 큐를 이용하는 라운드 로빈 방식의 스케쥴러를 코드로 표현해 볼게요.

보다 자세한 사항은 자료구조와 알조리즘 C++ 3.5 큐를 이용한 스케쥴러 시뮬레이션을 참고하세요.

EHProcess.H

#include 
using namespace std;
class EHProcess
{
    string pname; //프로그램 이름
    const int tjob; //전체 작업량
    const int cjob; //cpu 점유 시 수행가능 최대 작업량
    int ntjob; //현재 남은 작업량
    int ncjob; //현재 cpu 점유 시 수행가능 최대 작업량
public:
    EHProcess(string pname,int tjob,int cjob);
    void IdleToReady();//Idle 상태에서 Ready 상태로 전이
    int Running();//CPU를 점유하여 실행, 남은 작업량 반환
    void EndProgram(); //프로세스 종료
};

EHProcess.cpp

#include "EHProcess.h"
EHProcess::EHProcess(string pname,int tjob,int cjob):tjob(tjob),cjob(cjob)
{
    this->pname = pname;
}
void EHProcess::IdleToReady()//Idle 상태에서 Ready 상태로 전이
{
    cout<<pname<<" 총 작업량:"<<tjob<<" CPU 점유시 작업량:"<<cjob<<endl;
    ntjob = tjob; //프로그램 이미지 메모리에 로딩을 표현
}
#include 
int EHProcess::Running()//CPU를 점유하여 실행, 남은 작업량 반환
{
    cout << pname << " CPU 점유" << endl;
    ncjob = cjob; //ncjob에 CPU 사용할 수 있는 시간 대입    
    for(  ; ntjob && ncjob ; ntjob--, ncjob--)
    {
        Sleep(300);
        cout<<ntjob<<" ";//단위 시간 작업 수행을 표현
    }
    cout <<endl;//CPU를 반납함을 표현
    return ntjob; //남은 작업량 반환
}
void EHProcess::EndProgram() //프로세스 종료
{
    cout<<pname<<"종료"<<endl; //프로세스 종료를 표현
}

Scheduler.h

//Scheduler.h
#pragma once
#include 
#include 
using namespace std;
#include "EHProcess.h"
typedef vector Memory;
typedef queue ReadyQueue;
typedef Memory::iterator miter;
class Scheduler  
{
    Memory hard_disk; // 하드디스크
    ReadyQueue  rq; //대기 큐
public:
    Scheduler();
    void Simulation();//시뮬레이션 시작
    virtual ~Scheduler();
private:
    void Init(); //시뮬레이션 초기화- 프로그램 설치 및 실행 명령    
    void Ending();//시뮬레이션 종료
};

Scheduler.cpp

//Scheduler.h
#include "Scheduler.h"

Scheduler::Scheduler()
{
    Init();    
}
void Scheduler::Init()
{
    //하드디스크에 프로그램 설치를 표현
    hard_disk.push_back(new EHProcess("A",20,5));
    hard_disk.push_back(new EHProcess("B",23,6));
    hard_disk.push_back(new EHProcess("C",18,4));
    miter seek = hard_disk.begin();
    miter end = hard_disk.end();
    EHProcess *pro=0;    //하드디스크에 설치한 프로그램을 실행 명령을 표현
    for( ; seek != end ; ++seek)
    {
        pro = *seek;
        rq.push(pro); //대기 큐에서 기다림
        pro->IdleToReady();//Idle 상태에서 Ready상태로 전이
    }
}

Scheduler::~Scheduler()
{
    Ending();
}
void Scheduler::Ending()
{
    miter seek = hard_disk.begin();
    for(   ; seek != hard_disk.end(); ++seek)
    {
        delete (*seek); 
    }
}

void Scheduler::Simulation()
{
    EHProcess *process = 0;
    int job=0;
    while( !rq.empty() ) //대기 큐가 비어있지 않을 때
    {        
        process = rq.front();//가장 먼저 대기한 프로세스를 꺼냄
        rq.pop();

        job = process->Running();//꺼낸 프로세스를 실행
        if(job) //남은 작업이 있다면
        {
            rq.push(process); //대기큐에서 기다림
        }
        else
        {
            process->EndProgram();//프로세스 종료
        }
    }
}

Program.cpp

//Program.cpp
#include "Scheduler.h"
#include 
int main()
{
    Scheduler *sch = new Scheduler;    
    sch->Simulation();
    delete sch;    
    return 0;
}

실행 결과

A 총 작업량:20 CPU 점유시 작업량:5
B 총 작업량:23 CPU 점유시 작업량:6
C 총 작업량:18 CPU 점유시 작업량:4
A CPU 점유
20 19 18 17 16 
B CPU 점유
23 22 21 20 19 18 
C CPU 점유
18 17 16 15 
A CPU 점유
15 14 13 12 11 
B CPU 점유
17 16 15 14 13 12 
C CPU 점유
14 13 12 11 
A CPU 점유
10 9 8 7 6 
B CPU 점유
11 10 9 8 7 6 
C CPU 점유
10 9 8 7 
A CPU 점유
5 4 3 2 1 
A종료
B CPU 점유
5 4 3 2 1 
B종료
C CPU 점유
6 5 4 3 
C CPU 점유
2 1 
C종료