현재 포스팅은 반효경 교수님의 운영체제 강의 + 추가적인 내용을 바탕으로 정리된 글입니다 :)
0. CPU 스케쥴링 개요
기계어 명령은 크게 CPU 내에서 수행되는 명령, 메모리의 접근을 필요로 하는 명령, 입출력을 동반하는 명령으로 나누어 볼 수 있습니다.
CPU 내에서 수행되는 명령으로는 대표적으로 CPU 내의 레지스터에 있는 두 개의 값을 더해, 레지스터에 값을 저장하는 Add 명령이 있습니다. 이러한 명령은 CPU 내에서만 수행되므로, 수행 속도가 매우 빠릅니다.
메모리의 접근을 필요로 하는 명령에는 Load 명령과 Store 명령이 있습니다. Load는 메모리에 있는 데이터를 CPU로 읽어 들이는 명령이고, Store는 CPU에서 수행된 연산 결괏값을 메모리에 저장하는 명령입니다. 이러한 명령 또한 CPU 내에서 수행되는 명령보다 시간은 오래 걸리지만, 비교적 짧은 시간에 수행되는 명령입니다.
입출력을 동반하는 명령에는 키보드로 부터 입력받기, 처리된 결과를 화면에 출력하기, 디스크에서 파일 읽어 오는 작업 등이 있습니다. 이와 같이 IO 작업을 동반하는 명령은 CPU나 메모리 접근 명령에 비해 상당히 오래 걸립니다.
사용자 프로그램이 작동되는 과정을 지켜보면, CPU 작업과 I/O 작업의 반복으로 구성됩니다.
이때 사용자 프로그램이 CPU를 직접 가지고 빠른 명령을 수행하는(ex: Add, Load, Store) 일련의 단계를 CPU 버스트, I/O 요청이 발생해 커널에 의해 입출력 작업을 진행하는 비교적 느린 단계를 I/O 버스트라고 부릅니다.
좀 더 상세히 정의해 보자면 프로그램이 I/O를 한번 수행한 후 다음번 I/O를 수행하기까지 직접 CPU를 가지고 명령을 수행하는 작업을 CPU 버스트, I/O 작업이 요청된 후 완료되어 다시 CPU 버스트로 돌아가기까지의 일련의 작업을 I/O 버스트라고 하는 것입니다.
그리고 I/O 요청이 빈번해 CPU 버스트가 짧게 나타나는 프로세스를 I/O 바운드 프로세스, I/O 작업을 거의 수행하지 않아 CPU 버스트가 길게 일어나는 프로세스를 CPU 바운드 프로세스라고 부릅니다.
CPU 프로세싱은 이와 같이 CPU를 사용하는 패턴이 상이한 여러 프로그램이 동일한 시스템 내부에서 함께 실행되기에 필요한 것입니다!
일반적으로 프로세스들의 CPU 버스트를 분석해 보면, 대부분의 경우 짧은 CPU 버스트를 가지며, 극히 일부분만 긴 CPU 버스트를 가집니다. 즉 CPU를 한 번에 오래 사용하기보다는 잠깐 사용하고 I/O 작업을 수행하는 프로세스들이 많다는 것이죠!
따라서 대체로 짧은 CPU 버스트를 가진 프로세스에게 우선적으로 CPU를 할당하는 것이 이득일 수 있습니다.
왜냐하면 짧은 CPU 버스트를 가진 프로세스가 먼저 처리되면, 이 프로세스가 빨리 완료되어 다음 프로세스가 더 빨리 시작할 수 있을 뿐 아니라, 해당 프로세스가 차지하고 있는 I/O 등의 시스템 자원이 더 빨리 해제되어 다른 프로세스에게 할당될 수 있기 때문입니다.
하지만 위 경우에는 긴 CPU 버스트를 가진 프로세스는 계속해서 밀려날 수 있으며, 이를 기아현상이라고 부릅니다.
따라서 스케줄링 알고리즘은 시스템의 특성과 요구사항에 따라 적절히 선택되어야 합니다!
1. CPU 스케쥴러
CPU 스케쥴러는 준비 상태에 있는 프로세스들 중 어떠한 프로세스에게 CPU를 할당할지 결정하는 운영체제 코드입니다.
이러한 CPU 스케쥴러의 스케쥴링 방식에는 비선점형(non-preemptive) 방식과, 선점형 방식(preemptive)이 있습니다.
비선점형 방식이란 CPU를 획득한 프로세스가 스스로 CPU를 반납하기 전까지는 CPU를 빼앗기지 않는 방법을 뜻하고, 선점형 방식은 프로세스가 CPU를 계속 사용하기를 원하더라도 강제로 빼앗을 수 있는 스케쥴링 방법을 말합니다.
이러한 CPU 스케쥴링이 어떠한 경우에 필요한지 대표적인 상황 몇 가지를 알아보겠습니다!
- 실행 상태에 있던 프로세스가 I/O 요청 등에 의해 봉쇄 상태로 바뀌는 경우
- 실행 상태에 있던 프로세스가 타이머 인터럽트에 의해 준비 상태로 바뀌는 경우
- I/O 요청으로 봉쇄 상태에 있던 프로세스의 I/O 작업이 완료되어 인터럽트가 발생하고 그 결과 이 프로세스의 상태가 준비 상태로 바뀌는 경우
- CPU에서 실행 상태에 있는 프로세스가 종료되는 경우
위 4가지 경우 중 1,4은 비선점형 스케쥴링, 2,3은 선점형 스케쥴링 방식에 해당합니다.
3의 예시에 내용을 좀 더 추가해 보자면, I/O 작업이 완료된 프로세스가 인터럽트 당한 프로세스보다 우선순위가 높아, 인터럽트 처리 후 직전에 수행되던 프로세스에게 CPU를 다시 할당하는 것이 아니라 Context Switching을 통해 I/O가 완료된 프로세스에게 CPU를 할당하는 경우가 해당됩니다.
2. 디스패처
CPU 스케줄러가 어떤 프로세스에게 CPU를 할당해야 할지 결정하고 나면 선택된 프로세스에게 실제로 CPU를 이양하는 작업이 필요합니다. 이때 새롭게 선택된 프로세스가 CPU를 할당받고 작업을 수행할 수 있도록 환경설정을 하는 운영체제 코드를 디스패처(Dispatcher)라고 부릅니다.
이러한 디스패처는 현재 수행 중이던 프로세스의 문맥을 그 프로세스 PCB에 저장하고, 새롭게 선택된 프로세스의 문맥을 PCB로부터 복원한 후 프로세스에게 CPU를 넘기는 과정을 수행합니다.
이때 PCB 복원 후, 시스템의 상태를 사용자 모드로 전환해 사용자 프로그램에게 CPU 제어권을 넘기게 됩니다!
그러면 사용자 프로그램은 복원된 문맥 중 PC로부터 현재 수행할 주소를 찾고 작업을 재개할 수 있겠죠??
이때 디스패처가 진행하는 일련의 과정에 걸리는 시간을 디스패처 지연시간이라고 하며, 이의 대부분은 Context Switching의 오버헤드에 해당합니다.
3. 스케쥴링의 성능 평가
스케쥴링의 기법의 성능 평가하기 위한 지표는 크게 시스템 관점의 지표와 사용자 관점의 지표로 나뉩니다.
시스템 관점의 지표로는 CPU 이용률, 처리량 등이 있으며, 사용자 관점의 지표로는 소요시간, 대기시간, 응답시간 등이 있습니다.
CPU 이용률이란 전체 시간 중 CPU가 일을 한 시간의 비율을 나타냅니다. 고비용 자원인 CPU가 일을 하지 않고 휴먼(idle) 상태에 머무는 시간을 최대한 줄이는 것이 CPU 스케쥴링의 중요한 목표입니다.
처리량(Throughput)은 주어진 시간 동안 준비 큐에서 기다리고 있는 프로세스 중 몇 개를 끝마쳤는지를 의미합니다. 즉 CPU 서비스를 원하는 프로세스 중 몇 개가 원하는 만큼의 CPU를 사용하고, 이번 CPU 버스트를 끝내어 준비큐를 떠났는지 측정하는 것입니다.
처리량을 늘리기 위해서는 CPU 버스트가 짧은 프로세스에게 우선적으로 CPU를 할당하는 것이 아무래도 유리하겠죠???
소요시간(turnaround time)은 프로세스가 CPU를 요청한 시점부터 자신이 원하는 만큼 CPU를 다 쓰고 CPU 버스트가 끝나기까지 걸린 시간, 즉 준비 큐에서 기다린 시간과 실제로 CPU를 사용한 시간의 합을 뜻합니다.
이때 프로그램이 시작해서 종료하는 데 까지 걸리는 시간이 아님을 주의해야 합니다!
프로그램이 시작해서 종료하기까지 CPU 버스트는 여러 차례 있을 수가 있고, 현재 저희는 CPU에만 관심이 있기에 하나의 프로세스라 하더라도 소요시간은 CPU 버스트의 수만큼 각각 별도로 측정되기 때문입니다.
예를 들어 CPU를 사용하다가 I/O 연산을 위해 CPU를 자진반납했다면, CPU를 사용하기 위해 준비 큐에 들어왔을 때부터, CPU를 자진반납하기까지 걸린 시간이 소요시간이 되겠죠??
대기 시간(waiting time)은 CPU 버스트 기간 중 프로세스가 준비 큐에서 CPU를 얻기 위해 기다린 시간의 합을 뜻합니다.
시분할 시스템의 경우엔 일반적으로 타이머 인터럽트로 인해 한 번의 CPU 버스트 중에도 준비 큐에서 기다리는 시간이 여러 번 발생할 수 있겠죠?? 대기 시간은 이때 준비큐에서 기다린 시간들의 총합입니다!
응답 시간(response time)은 프로세스가 준비 큐에 들어온 후 첫 번째 CPU를 획득하기까지 기다린 시간을 뜻합니다.
앞서 설명드린 대기 시간은 준비 큐에 들어온 직후, 이번 CPU 버스트가 끝날 때까지 준비 큐에서 기다린 시간의 합을 나타내는 반면, 응답시간은 준비 큐에 들어온 직후부터 첫 번째 CPU를 얻기까지 걸린 시간만을 나타내어 이 두 척도는 다소 차이가 있습니다.
타이머 인터럽트가 빈번할수록 이러한 응답시간은 향상되며, 이는 대화형 시스템의 적합한 성능척도입니다
4. 스케줄링 알고리즘
지금부터는 다양한 스케줄링 알고리즘에 대해 살펴보겠습니다 :)
1) 선입선출 알고리즘(First-Come First-Served : FCFS)
선입선출 스케줄링은 프로세스가 준비 큐에 도착한 순서대로 CPU를 할당하는 방식으로, 비 선점형 방식입니다.
이는 합리적인 스케줄링 방식처럼 보이지만, 경우에 따라 비효율적인 결과를 초래하기도 합니다.
예를 들어 CPU 버스트가 긴 프로세스 하나가 CPU 버스트가 짧은 여러 프로세스보다 먼저 도착했다고 가정해 보겠습니다!
이때 CPU를 잠깐만 사용하면 준비 큐를 떠나 I/O 작업을 수행할 수 있는 다수의 프로세스들이 하나의 긴 작업 때문에 평균 대기 시간이 길어질 뿐만 아니라 I/O 장치들의 이용률까지 동반 하락하게 됩니다.
첫 번째 차트의 경우엔 CPU 버스트 시간이 긴 P1 프로세스가 먼저 도착한 경우입니다.
이 경우 평균 대기 시간은 (0+24+27) / 3 = 16.7입니다.
반면 두 번째 차트의 경우는 CPU 버스트 시간이 짧은 두 프로세스(ex: I/O 작업이 많은 프로세스)가 버스트 시간이 긴 P1보다 먼저 도착한 경우입니다.
이 경우엔 평균 대기 시간이 (0+3+6)/3 = 3입니다.
두 차트를 비교해 보았을 때, CPU 버스트가 짧은 프로세스가 먼저 도착한 두 번째 경우에 평균 대기 시간이 크게 줄어들었음을 알 수 있습니다. 첫 번째 경우처럼 CPU 버스트가 짧은 프로세스가 CPU 버스트가 긴 프로세스 보다 나중에 도착해 오랜 시간을 기다려야 하는 현상을 콘보이 현상(Convoy Effect)라고 하며, 이는 FCFS 스케쥴링 기법의 대표적인 단점에 해당합니다!
2) 최단 작업 우선 스케쥴링(Shortest Job First: SJF)
SJF 스케쥴링은 CPU 버스트가 가장 짧은 프로세스에게 제일 먼저 CPU를 할당하는 방식으로, 이 또한 비 선점형 방식으로 동작합니다.
이는 평균 대기 시간을 가장 짧게 하는 최적 알고리즘으로 알려져 있습니다.
SJF 스케쥴링은 비선점형 방식과 선점형 방식 두 가지로 구현될 수 있습니다. SJF을 선점형으로 구현할 시 현재 CPU에서 실행 중인 프로세스의 남은 CPU 버스트 시간보다 더 짧은 CPU 버스트 시간을 가지는 프로세스가 도착하면 CPU를 빼앗기게 됩니다.
이러한 SJF의 선점형 구현 방식을 SRTF(Short Remaining Time First)라고도 부릅니다.
그렇다면 어떠한 경우에 선점형 방식을 사용하는 것이 좋을까요??
일반적으로 CPU를 기다리는 프로세스들이 준비 큐에 동시에 도착하지는 않습니다. 프로세스들이 준비 큐에 도착하는 시간이 불규칙한 환경에서는 선점형 방식이 프로세스들의 평균 시간을 최소화하는 최적의 알고리즘이 됩니다.
일반적으로 시분할 환경에서는 중간중간에 새로운 프로세스가 준비 큐에 도착하는 경우가 발생하므로, 선점형 방식이 유용하겠죠??
위 표에서 P1, P2, P3, P4의 프로세스가 각각 위와 같은 도착시간과 CPU 버스트 시간을 가진다고 할 때, SJF 알고리즘의 평균 대기 시간은 다음과 같습니다.
SJF의 비선점형 스케줄링 방법 : (0 + 12 + 6 + 14) / 4 = 8
SJF 선점형 스케쥴링 방법 : (18 + 2 + 0 + 4) / 4 = 6
현재 괄호 안의 값들은 P1부터 P4까지 대기시간을 순서대로 적어놓았습니다! 계산을 직접 해보고 싶으신 분들은 위 개념을 참고해서 직접 풀어보시는 걸 추천드려요!
이러한 SJF 스케줄링 기법의 구현에서 현실적으로 어려운 부분은 CPU 버스트 시간을 미리 알 수 없다는 점입니다.
그래서 예측을 통해 CPU 버스트 시간을 구한 후 예측치가 가장 짧은 프로세스에게 CPU를 할당하게 됩니다.
또한 SJF 알고리즘이 평균 대기 시간을 최소화하는 최적의 알고리즘이지만, 시스템에서 평균 대기 시간을 줄이는 것이 항상 좋은 방법이라고는 할 수 없습니다
만약 계속 CPU 버스트가 짧은 프로세스에게만 CPU를 할당할 경우, CPU 버스트가 긴 프로세스는 준비 큐에 줄 서서 무한정 기다려야 하는 문제가 발생할 수 있기 때문입니다. 이러한 현상을 기아 현상(starvation)이라고 하며, 이는 SJF 알고리즘의 심각한 문제점이 됩니다!
3) 우선순위 스케줄링(Priority Scheduling)
우선순위 스케줄링이란 준비 큐에서 기다리는 프로세스들 중 우선순위가 가장 높은 프로세스에게 제일 먼저 CPU를 할당하는 방식을 말합니다.
이때 우선순위는 priority number를 통해 표시하며, 우선순위 값이 작을수록 높은 우선순위를 가지는 것으로 가정합니다.
우선순위를 결정하는 방식에는 여러 가지가 있을 수 있습니다!
예를 들어 CPU 버스트 시간을 우선순위 값으로 정의하거나(이 경우엔 SJF 알고리즘과 동일한 의미), 시스템과 관련된 중요한 작업을 수행하는 프로세스의 우선순위를 높게 부여하는 경우가 있을 것입니다.
이러한 우선순위 스케줄링 또한 SJF과 같이 비선점형 방식과 선점형 방식으로 각각 구현할 수 있습니다!
우선순위 스케줄링은 앞선 SJF와 같이 starvation이 발생할 수 있습니다. 우선순위가 높은 프로세스가 계속 도착하는 상황에서는 우선순위가 낮은 프로세스는 CPU를 얻지 못한 채 계속 기다려야 할 수 있기 때문입니다.
이러한 starvation을 해결하기 위해 보통 노화(aging) 기법을 사용합니다.
노화 기법은 프로세스의 기다리는 시간이 길어지면 우선순위를 조금씩 높여, 언젠가는 가장 높은 우선순위가 되어 CPU를 할당받을 수 있게 해주는 방법입니다.
4) 라운드 로빈 스케쥴링(Round Robin Scheduling)
라운드 로빈 스케줄링은 지금까지 소개한 스케줄링 방식과 달리 시분할 시스템의 성질을 가장 잘 활용한 스케줄링 방식으로, 각 프로세스가 CPU를 연속적으로 사용할 수 있는 시간을 특정 시간으로 제한하고, 시간 경과 시 해당 프로세스로부터 CPU를 회수해 준비 큐에 줄 서 있는 다른 프로세스에게 CPU를 할당합니다.
라운드 로빈에서 만약 할당 시간을 너무 크게 한다면 FCFS처럼 동작하게 되고, 너무 짧다면 Context Switching(문맥 교환) 오버헤드가 커지기 때문에 적절한 시간을 할당하는 것이 중요합니다!
라운드 로빈에서 만약 n개의 프로세스가 준비 큐에 있고 할당시간이 q라면, 모든 프로세스는 (n-1) q 시간 이내에 적어도 한 번은 CPU를 할당받을 수 있습니다. 즉 빠른 응답 시간을 보장할 수 있다는 장점이 있습니다!(SJF 방식보다 평균 대기 시간은 길다)
또한 SJF나 우선순위 스케줄링과 다르게, CPU 버스트가 긴 프로세스에게 특별히 불이익이 가는 것도 아닙니다.
왜냐하면 각 프로세스의 대기시간이 그 프로세스의 CPU 버스트 시간에 비례하기 때문입니다! 즉 CPU를 많이 쓰는 프로세스는 대기 시간이 그에 비례해 길어지고, 반대로 CPU를 적게 쓰는 프로세스는 대기시간도 짧아지게 됩니다.
지금부터는 FCFS 스케줄링과 라운드 로빈 스케쥴링을 대기시간, 응답시간, 소요시간 관점에서 한번 비교해보겠습니다!
간단히 다시 짚고 가자면 소요시간은 CPU 버스트가 끝나기까지 걸린 시간(대기 시간 포함), 대기 시간은 프로세스가 준비 큐에서 CPU를 얻기 위해 기다린 시간의 총합, 응답 시간은 프로세스가 준비 큐에 들어온 후 첫 번째 CPU를 획득하기까지 기다린 시간을 뜻합니다.
예를 들어 버스트 시간이 10인 프로세스 10개가 간발의 차이로 모두 시각 0에 도착했다고 가정해 봅시다.
이 경우 FCFS에서 대기 시간은 각각 0,10,20..... 90이고, 응답시간 또한 이와 같을 것입니다(CPU 할당을 처음 받고 바로 작업을 끝내기에)
이때 FCFS의 평균 대기 시간과 평균 응답시간은 모두 45가 됩니다.
소요 시간의 경우에는 10,20,30.... 100으로 증가하고, 평균 소요 시간은 55가 됩니다.
이러한 FCFS는 적어도 하나씩은 처리가 완료된 프로세스가 발생하여 평균 대기시간이나 평균 응답시간 측면에서 좋은 결과를 얻을 수 있지만, 프로세스 간 대기시간이나 소요시간의 편차가 매우 크며, 평균 응답시간이 지나치게 길어질 수 있습니다.
만약 라운드 로빈 스케줄링을 위 상황에 적용하면 어떨까요??
할당시간을 극단적으로 짧게 설정하였다면 100이라는 시간 안에 거의 동시에 자신의 CPU 버스트를 마치기에 대기시간과 처리시간의 편차가 크지 않지만, 각각 90과 100에 이르게 되어 FCFS 보다 비효율적입니다.
즉 FCFS에서는 CPU를 먼저 쓰고 나가는 프로세스의 소요시간 및 대기시간이 짧아지는 반면, 라운드 로빈에서는 CPU를 조금씩 같이 쓰고 거의 동시에 끝나게 되어 소요시간 및 대기시간이 가장 오래 기다린 프로세스에 맞추어지게 되는 것입니다.
하지만 평균 응답시간은 당연히 짧아지겠죠??
두 스케쥴링을 일반적인 시스템에서 비교해 보자면, 라운드 로빈의 경우엔 프로세스의 CPU 사용량에 비례해 소요시간이 증가하므로 합리적이지만, FCFS는 프로세스마다 소요되는 시간의 편차가 매우 큽니다.
5) 멀티레벨 큐(Multi-level-queue)
멀티 레벨 큐는 준비큐를 여러 개로 분할해 관리하는 스케줄링 기법을 의미합니다.
이는 일반적으로 성격이 다른 프로세스들을 별도로 관리하고, 프로세스의 성격에 맞는 스케줄링을 적용하기 위해 별도의 준비큐를 두게 됩니다. 예를 들어 대화형 작업과 그렇지 않은 작업이 있다면, 이 두 타입의 작업들을 별도의 큐에 줄을 세웁니다. 이후 대화형 작업이 기다리고 있다면 이들에게 우선적으로 CPU를 할당하고 대화형 작업이 없을 때 나머지 작업에게 CPU를 할당하는 것이죠
일반적으로 멀티레벨 큐에서 준비 큐는 대화형 작업을 담기 위한 전위 큐(foreground queue)와 계산 위주의 작업을 담기 위한 후위 큐(background queue)로 분할하여 운영됩니다. 이때 전위 큐에는 응답시간을 짧게 하기 위해 라운드 로빈 스케줄링을 사용하는 반면, 계산 위주의 작업에서는 응답시간이 큰 의미를 가지지 않기에 FCFS 기법을 사용해 문맥교환의 오버헤드를 줄이도록 합니다.
멀티 레벨 큐에는 여러 준비 큐가 존재하기에 어느 큐에 먼저 CPU를 할당할지 결정하는 스케줄링 또한 필요합니다!
이러한 스케줄링 방식에는 고정 우선순위 방식과 타임 슬라이스 방식이 있습니다.
고정 우선순위는 말 그대로 큐마다 고정적인 우선순위를 부여하여 스케줄링하는 것이고, 타임 슬라이스 방식은 큐에 대한 기아 현상을 해소하는 방식으로 각 큐에 CPU시간을 적절한 비율로 할당하는 것입니다(ex: 전위 큐 : 80%, 후위 큐 : 20%)
6) 멀티레벨 피드백 큐
멀티 레벨 피드백 큐는 CPU를 기다리는 프로세스를 여러 큐에 줄 세운다는 측면에서 멀티 레벨 큐와 동일하나, 프로세스가 하나의 큐에서 다른 큐로 이동 가능하다는 점이 다릅니다.
예를 들어 우선순위 스케줄링에서 기아 현상을 해결하기 위해 등장했던 aging 기법을 멀티레벨 피드백 큐로 구현하고자 한다면, 우선순위가 낮은 큐에서 오래 기다렸다면 우선순위가 높은 큐로 승격시키는 방식으로 구현할 수 있을 것입니다.
이러한 멀티레벨 피드백 큐는 기본적으로 프로세스가 주어진 시간 할당량 내에 작업을 마치지 못하면, 그 프로세스를 낮은 우선순위로 이동시키고, 프로세스가 시간 할당량 전에 작업을 완료하면, 그 프로세스는 높은 우선순위의 큐로 이동할 수 있는 방식으로 동작합니다. 이러한 멀티 레벨 피드백 큐를 정의하는 요소로는 큐의 수, 각 큐의 스케줄링 알고리즘, 상위 큐로 승격 기준, 하위큐로 강등 기준, 프로세스가 도착했을 때 들어갈 큐를 결정하는 기준 등이 있을 것입니다
결론적으로 멀티레벨 피드백 큐는 라운드 로빈 스케줄링을 한층 더 발전시켜, 프로세스의 CPU 작업 시간을 다단계로 분류함으로써 작업시간이 짧은 프로세스일수록 더욱 빠른 서비스가 가능하도록 하고, 작업 시간이 긴 프로세스에 대해서는 문맥 교환 없이 CPU 작업에만 열중할 수 있는 FCFS 방식을 채택할 수 있게 하는 것입니다.
개발자 준비생이 대학 강의를 듣고 정리한 내용입니다
혹시 틀린 내용이 있다면 댓글 부탁드리겠습니다!! 곧바로 수정하겠습니다
'운영체제 > 반효경 교수님 - 운영체제 강의' 카테고리의 다른 글
운영체제 7강 - 가상 메모리 (0) | 2023.06.10 |
---|---|
운영체제 6강 - 메모리 관리 (1) | 2023.06.09 |
운영체제 4강 - 프로세스 관리 (2) | 2023.06.07 |
운영체제 3강 - 프로그램 구조와 실행 (2) | 2023.06.07 |
운영체제 2강 - 컴퓨터 시스템의 동작 원리 (2) | 2023.06.06 |