From 782e14c7dc952d74a70a0fc5d1276af6ecd38232 Mon Sep 17 00:00:00 2001 From: Ogu1208 Date: Sun, 11 Jun 2023 02:41:20 +0900 Subject: [PATCH 1/2] [feat]: create SRT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Shortest Remaining Job 스케줄링 구현 기본적으로 라운드 로빈 스케줄링을 사용하지만, CPU를 할당받을 프로세스를 선택할 때 남아 있는 작업 시간이 가장 적은 프로세스를 선택 --- src/Main.java | 13 +++++ src/RoundRobin.java | 2 +- src/SRT.java | 119 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 src/SRT.java diff --git a/src/Main.java b/src/Main.java index bc7f767..36744a9 100644 --- a/src/Main.java +++ b/src/Main.java @@ -14,6 +14,8 @@ public static void main(String[] args) { hrn(); System.out.println("-----------------RR-----------------"); rr(); + System.out.println("-----------------SRT-----------------"); + srt(); } @@ -80,6 +82,17 @@ public static void rr() display(rr); } + public static void srt() + { + CPUSchedulingAlgorithm srt = new SRT(); + srt.setTimeQuantum(10); + srt.addRow(new Row("P1", 0,30)); + srt.addRow(new Row("P2", 3, 18)); + srt.addRow(new Row("P3", 6, 9)); + srt.process(); + display(srt); + } + public static void display(CPUSchedulingAlgorithm object) { System.out.println("Process\tAT\tBT\tWT\tTAT\tRT"); diff --git a/src/RoundRobin.java b/src/RoundRobin.java index 71ad74f..1d1067c 100644 --- a/src/RoundRobin.java +++ b/src/RoundRobin.java @@ -41,7 +41,7 @@ public void process() { // 만약 프로세스의 burstTime이 timeQuantum보다 크다면 if (row.getBurstTime() > timeQuantum) { - // burtTime을 bursttime - timeQuantum으로 갱신 + // burtTime을 burstTime - timeQuantum으로 갱신 row.setBurstTime(row.getBurstTime() - timeQuantum); // timequantum만큼 일한 프로세스 row를 큐의 뒤에 추가 diff --git a/src/SRT.java b/src/SRT.java new file mode 100644 index 0000000..27988eb --- /dev/null +++ b/src/SRT.java @@ -0,0 +1,119 @@ +import java.util.*; + +public class SRT extends CPUSchedulingAlgorithm { + @Override + public void process() { + // Sort list of objects using Collection.sort() with lambdas only + // 도착시간(ArrivalTime)을 기준으로 빠른순으로 정렬한다. (도착한 순서대로) + Collections.sort(this.getRows(), (Object o1, Object o2) -> { + if (((Row) o1).getArrivalTime() == ((Row) o2).getArrivalTime()) { + return 0; + } else if (((Row) o1).getArrivalTime() < ((Row) o2).getArrivalTime()) { + return -1; + } else { + return 1; + } + }); + + // rows = this.getRows를 깊은 복사 + List rows = Utility.deepCopy(this.getRows()); + int time = rows.get(0).getArrivalTime(); // 첫 번째 프로세스의 도착시간 + + // time Quantum 설정 + int timeQuantum = this.getTimeQuantum(); + + while (!rows.isEmpty()) { + // available Row의 List를 만든다. + List availableRows = new ArrayList(); + + // for문을 돌며 time보다 row의 도착시간이 작거나 같으면 available Row에 추가한다. + for (Row row : rows) { + if (row.getArrivalTime() <= time) { + availableRows.add(row); + } + } + + // burstTime이 작은(남아있는 작업 시간이 가장 적은 순)으로 정렬한다. (Shortest Remaining Time) + Collections.sort(availableRows, (Object o1, Object o2) -> { + if (((Row) o1).getBurstTime() == ((Row) o2).getBurstTime()) { + return 0; + } else if (((Row) o1).getBurstTime() < ((Row) o2).getBurstTime()) { + return -1; + } else { + return 1; + } + }); + + // 가능한 rows들 중 burstTime이 가장 적은 row(process)를 구한다. + Row row = availableRows.get(0); + + // 한 텀의 burst time 계산 + // (timeQuantum보다 burstTime이 작으면 burstTime만큼, 아니라면 timeQuantum만큼 실행) + int bt = (row.getBurstTime() < timeQuantum ? row.getBurstTime() : timeQuantum); + + // timeline(List)에 burstTime이 가장 작은(남아있는 작업 시간이 가장 적은) row(process)의 Event를 추가 + // startTime : time + // finishTime : time + row의 bt + this.getTimeline().add(new Event(row.getProcessName(), time, time + bt)); + time += bt; // time 갱신 (timme+=bt) + + // row의 burstTime = burstTime - bt 로 업데이트 + row.setBurstTime(row.getBurstTime() - bt); + + // 만약 해당 process의 burstTime이 끝났다면, 같은 이름의 프로세스를 찾아 rows행에서 remove시킨다. + if (row.getBurstTime() == 0) { + for (int i = 0; i < rows.size(); i++) { + if (rows.get(i).getProcessName().equals(row.getProcessName())) { + rows.remove(i); + break; + } + } + } + } + + // for문으로 Event의 List를 뒤에서부터 거꾸로 찾으면서 + for (int i = this.getTimeline().size() - 1; i > 0; i--) { + List timeline = this.getTimeline(); + + // timeline의 마지막 프로세스와 마지막-1의 프로세스가 같다면 + if (timeline.get(i - 1).getProcessName().equals(timeline.get(i).getProcessName())) { + // 마지막-1의 프로세스의 finishTime을 마지막 프로세스의 finishTime으로 업데이트하고 + timeline.get(i - 1).setFinishTime(timeline.get(i).getFinishTime()); + // 마지막 프로세스를 삭제한다. + timeline.remove(i); + } + } + + Map map = new HashMap(); + + // for문을 돌며 row와 evnet 비교 + for (Row row : this.getRows()) { + map.clear(); + + // waitingTime = 시작 시작 - 도착 시간 + for (Event event : this.getTimeline()) { + // row와 evnet의 프로세스 이름이 같으면 + if (event.getProcessName().equals(row.getProcessName())) { + // map에 프로세스 이름의 key가 있다면 (이미 한번 이상 burstTime만큼 작업했다면) + if (map.containsKey(event.getProcessName())) { + // 기존 waitingTime에 (이전에 작업했을 때의 finishTime - 이번 작업의 startTime)을 더함. + int w = event.getStartTime() - (int) map.get(event.getProcessName()); + row.setWaitingTime(row.getWaitingTime() + w); + } + // 아직 map에 프로세스 이름의 key가 없다면 + else { // row의 waitingTime을 startTime - ArrivalTime으로 초기화 + row.setWaitingTime(event.getStartTime() - row.getArrivalTime()); + } + + // map에 key : processName, value: finishTime을 삽입 + map.put(event.getProcessName(), event.getFinishTime()); + } + } + + // turnAroundTime = 대기 시간 + 실행 시간(burst time) + row.setTurnaroundTime(row.getWaitingTime() + row.getBurstTime()); + // responseTime = 첫 작업을 시작한 후 첫 번째 출력(반응)이 나오기 전까지 시간 + row.setResponseTime(row.getWaitingTime() + 1); + } + } +} \ No newline at end of file From bb2a3b5fe03fabb5d6fff959c4e882fa50a02ddf Mon Sep 17 00:00:00 2001 From: KIM MINA Date: Sun, 11 Jun 2023 02:42:51 +0900 Subject: [PATCH 2/2] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f100f3e..7f090ca 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ - FCFS - SJF(Shortest Job First) +- HRN - Priority Non Preemptive - Priority Preemptive -- HRN - RoundRobin - SRT(Shortest Remaining Time)