2024/05/17
운영체제
운영체제란?
운영체제(OS, Operating Sysetm)란 하드웨어 위에 설치되어 하드웨어 계층과 다른 소프트웨어 계층을 연결하는 소프트웨어 계층이다.
컴퓨터 시스템의 자원을 관리하고, 사용자가 컴퓨터를 사용할 수 있는 환경을 제공하는 역할을 수행한다.
CPU, 메모리 같은 컴퓨터 자원은 제한적이라서 이러한 자원을 관리하는 일은 매우 중요하다. 또한 사용자와 컴퓨터 간 인터페이스를 제공해 사용자가 컴퓨터를 편리하게 사용할 수 있는 환경을 제공한다. 대표적인 OS로는 윈도우(Windows), 맥(OS), 리눅스(Linux), 유닉스(Unix) 등이 존재한다.
컴퓨터에서 운영체제의 위치
운영체제의 목적
OS는 한정된 컴퓨터의 자원을 관리하는 시스템이다. 이러한 역할에 기반해 OS는 4가지 목적이 존재한다.
- 처리 능력(throughput)향상: OS는 자원 관리를 통해 일정 시간 내에 시스템이 처리하는 일의 양을 향상시킨다.
- 반환 시간(turnaround time)단축: OS는 사용자가 시스템에 요청한 작업을 완료할 때까지 소요되는 시간을 단축시킨다.
- 사용 가능도(availability) 향상: 사용 가능도는 시스템 자원을 얼마나 빨리 제공할 수 있는가를 의미한다. OS는 사용자가 컴퓨터를 사용해야 할 때 자원을 즉시 사용할 수 있게 된다.
- 신뢰도(reliability)향상: 신뢰도는 시스템이 주어진 문제를 정확하게 푸는지를 의미한다. OS는 입력 값에 대한 정확한 결과 값을 줄 수 있도록 신뢰도를 향상해야 한다.
CPU와 메모리 구조
CPU(Central Processing Unit, 중앙 처리 장치)는 컴퓨터의 뇌 역할을 하며, 컴퓨터에서 프로그램을 실행하는 데 필요한 연산을 처리하고 수행한다. 다른 말로 프로세서라고 한다.
메모리는 데이터를 저장하기 위한 기억장치로, 휘발성 메모리인 주 기억장치와 비휘발성 메모리인 보조 기억장치가 있다. 주 기억장치는 메인 메모리를 의미하며 일반적으로 RAM을 가리킨다. 보조 기억 장치는 SSD(Solid State Drive), HDD(Hard Disk Drive)등이 해당한다.
메모리는 CPU에서 빨리 접근할 수 있또록 다음과 같은 계층 구조를 가진다.
- 레지스터(register): CPU가 사용자 요청을 처리하는 데 필요한 데이터를 임시로 저장하는 기억장치이다. CPU 내부에 존재하며 접근 속도가 빠르다.
- 캐시 메모리(cache memory): CPU와 RAM 사이의 속도 차이를 해결하기 위한 기억장치다. CPU 내부에 위치하며 접근 속도가 레지스터 다음으로 빠르다.
- RAM(Random Access Memory): 컴퓨터에서 프로그램을 실행할 때 필요한 정보를 저장한다. CPU에서 접근 속도가 하드 디스크보다 빠르고, 휘발성 기억장치다. 보통 메모리라고 할 때 RAM을 의미하는 경우가 많다.
- 하드 디스크(hard disk): 사용자가 필요한 데이터와 프로그램을 저장하고, 비휘발성 기억장치다.
프로그램을 실행하면 OS가 디스크에 있는 프로그램을 메모리로 로드(load)한다. 메모리에 로드한 프로그램을 프로세스(process)라고 하며, CPU가 처리한다. CPU는 하나의 프로세스만 처리할 수 있어서 멀티 프로세스 환경에서는 OS가 스케줄링을 통해 CPU에 프로세스를 할당한다.
커널과 시스템 콜
커널(kernel)은 OS의 핵심 요소로, 컴퓨터 하드웨어와 프로세스의 보안, 자원 관리, 하드웨어 추상화 같은 중요한 역할을 수행한다. 특히 자원 관리를 위해 CPU 스케줄링, 메모리 관리, 입출력 관리, 파일 시스템 관리 등을 담당한다.
2024/05/18
운영체제는 커널에서 관리하는 중요 자원에 사용자가 쉽게 접근하지 못하도록 커널 모드(kernel mode)와 사용자 모드(user mode)로 모드를 나눈다. 커널 모드에서는 하드웨어에 직접 접근해 메모리, CPU와 같은 자원을 사용할 수 있다. 사용자 모드에서는 커널 모드의 자원에 접근할 수 없게 제한을 둔다.
사용자 모드에서 실행된 프로세스가 자원에 접근하려면 시스템 콜을 호출해 커널에 요청해야 한다.
시스템콜은 사용자 모드에서 커널 모드에 접근해 필요한 기능을 수행할 수 있게 하는 시스템 함수이다. 커널은 시스템 콜로 받은 요청을 처리한 후 다시 시스템 콜로 결과 값을 반환한다.
시스템 콜을 사용해 프로세스 제어, 파일 조작, 장치 관리, 데이터의 유지 보수, 통신, 보호를 할 수 있다. 시스템 콜의 대표적인 예로는
프로세스를 생성하는 fork(), 부모 프로세스가 자식 프로세스의 수행을 기다리는 wait()등이 있다.
하나 더 알기
시스템 콜에서 커널에 매개변수를 전달하는 방법은 3가지다.
(1) 매개변수를 CPU의 레지스터에 직접 전달하는 방식이다. 이 방식은 매개변수의 개수가 레지스터의 개수보다 많은 경우 문제가 될 수 있어서 권장하지 않는다.
(2) 매개변수를 메모리에 저장한 후 메모리의 주소 값을 레지스터에 저장하는 방식이다.
(3) 매개변수를 프로그램의 스택(stack)에 push하고 OS에서 pop해서 매개변수를 전달하는 방식
프로세스
프로세스와 스레드
프로세스
프로세스는 컴퓨터에서 실행 중인 하나의 프로그램을 의미한다. 프로그램은 특정 작업을 수행하기 위한 명령어의 집합이다.
OS는 프로그램을 실행하면서 디스크에 저장된 데이터를 메모리로 로드한다. 프로세스는 OS로부터 독립된 메모리 영역(코드, 데이터, 스택, 힙)을 할당받으며, 다른 프로세스의 메모리 영역에 접근할 수 없다.
프로세스에 할당된 메모리 영역은 다음과 같다. PCB는 프로세스 제어 블록이라고 한다.
프로세스의 메모리 영역 구조를 간단히 표현
- 스택(stack): 지역 변수, 함수의 매개변수, 반환되는 주소 값 등이 저장되는 영역이다. 높은 주소 값에서 낮은 주소 값으로 메모리가 할당되며, 영역 크기는 컴파일 때 결정된다.
- 힙(heap): 사용자에 의해 동적 메모리 할당이 일어나는 영역이다. C언어에서 malloc()으로 할당되는 영역이라고 보면 된다. 낮은 주소 값에서 높은 주소 값으로 메모리가 할당되며, 영역 크기는 런타임 때 결정된다.
- 데이터(data): 전역 변수, 정적 변수, 배열, 구조체 등이 저장되는 영역이다. 데이터 영역은 세부적으로 BSS(Block Stated Symbol) 영역과 데이터 영역으로 다시 나눌 수 있다. BSS 영역은 초기화하지 않은 변수를, 데이터 영역은 초기화한 변수를 저장한다.
- 코드(code): 실행할 코드가 기계어로 컴파일되어 저장되는 영역으로, 텍스트 영역이라고 한다.
스택 영역과 힙 영역은 동적으로 메모리 할당이 가능해 두 영역 사이에 빈 메모리 공간이 존재한다. 스택 영역은 LIFO(Last In First Out, 후입선출) 방식으로, 높은 주소 값에서 낮은 주소 값 순서로 사용한다. 힙 영역은 FIFO(First In First Out, 선입선출) 방식으로, 낮은 주소 값에서 높은 주소 값 순서로 사용한다.
메모리 영역을 공유하기 때문에 서로의 영역을 침범하는 문제가 생길 수 있다. 스택 영역이 힙 영역을 침범하는 경우를 스택 오버플로(stack overlfow), 힙 영역이 스택 영역을 침범하는 경우를 힙 오버플로(heap overflow)라고 한다.
용어사전
- 오버플로(overflow): 메모리 공간에서 할당할 수 있는 최대 범위를 넘어가는 것을 의미
- 언더플로(underflow): 메모리 공간에서 할당할 수 있는 최소 범위보다 작은 것을 의미
스레드
프로세스는 한 개 이상의 스레드를 갖는다. 스레드는 프로세스에서 실제로 실행되는 흐름의 단위를 의미한다.
스레드는 프로세스 안에 존재하므로 프로세스의 메모리 공간을 이용하고, 지역 변수를 저장하는 스택영역을 할당받는다.
전역 변수를 저장하는 힙 영역은 다른 스레드와 공유한다.
깊게 알기 [사용자 레벨 스레드와 커널 레벨 스레드]
커널에서 관리하는 자원을 보호하기 위해 내부적으로 사용자 모드와 커널 모드로 구분한다. 이와 마찬가지로 스레드도 스레드를 관리하는
주체에 따라 구분된다. 사용자 레벨 스레드(user-level-thread)는 사용자가 라이브러리를 이용해 생성 및 관리한다. 커널 레벨 스레드(kernel-level-thread)는 커널이 스레드를 생성 및 관리한다.
멀티 스레드 환경에서 사용자 레벨 스레드와 커널 레벨 스레드는 다음과 같이 3가지 관계를 맺는다.
1. 다대일 모델(many-to-one model)
사용자가 레벨 스레드 n개에 커널 레벨 스레드 1개가 매칭되어 사용자 레벨에서 스레드를 관리한다. 하나의 사용자 레벨 스레드에서 시스템 콜을 호출하면 나머지 사용자 레벨 스레드는 커널에 접근할 수 없으므로 멀티 코어의 병렬성을 이용할 수 없다.
2. 일대일 모델(one-to-one model)
사용자 레벨 스레드 1개에 커널 레벨 스레드 1개가 매핑된다. 이 방식은 하나의 사용자 레벨 스레드에서 시스템 콜을 호출하면 다른 사용자 레벨 스레드가 모두 실행되지 않는 다대일 모델의 단점을 해결한다. 하지만 사용자 레벨 스레드 수만큼 커널 레벨 스레드가 생성되므로 성능 저하가 일어날 수 있다.
3. 다대다 모델(many-to-many model)
사용자 레벨 스레드 n개에 커널 레벨 스레드 m개가 매핑된다. 커널 레벨 스레드의 수(m)는 사용자 레벨 스레드의 수(n)이하다.
다대일과 일대일 모델의 장점을 포함하지만, 구현이 어렵다.
PCB
OS는 프로세스를 제어하기 위해 프로세스 정보를 저장하는데, 이를 PCB(Process Control Block, 프로세스 제어 블록)라고 한다.
PCB는 프로세스의 현재 상태, 프로세스를 나타내는 고유의 PID(Process ID), 부포 프로세스의 PID, 자식 프로세스의 PID
다음 실행할 명령어 주소인 PC(Program Counter, 프로그램 카운터), 프로세스의 우선순위, 메모리 제한 등을 저장한다.
PCB에 저장되는 정보를 정리한 그림
프로세스의 생성
새로운 프로세스는 기존 프로세스에 fork()함수를 호출해 생성
fork()함수에는 함수를 호출한 프로세스를 복사하는 기능이 존재
기존 프로세스를 부모 프로세스, 복사된 프로세스를 자식 프로세스라고 한다.
부모 프로세스에서 fork()함수를 호출하면 부모 프로세스는 자식 프로세스의 PID 값을, 자식 프로세스는 0을 반환한다.
하나 더 알기
운영체제가 프로세스를 종료하는 경우
(1) 프로세스가 운영체제의 종료 서비스 (exit())를 호출해 정상 종료하는 경우
(2) 프로세스의 실행 시간 또는 특정 이벤트 발생을 기다리는 시간이 제한된 시간을 초과한 경우
(3) 프로세스가 파일 검색 또는 입출력에 실패하는 경우
(4) 오류가 발생하거나 메모리 부족 등이 발생하는 경우
부모 프로세스가 자식 프로세스를 종료시키는 경우
(1) 자식 프로세스가 할당된 자원을 초과해 사용할 때
(2) 자식 프로세스가 할당된 작업이 없을 때
2024/05/21
깊게 알기
fork() 함수의 반환값
ForkSample.c
#include<stdio.h>
#include<unistd.h>
int main() {
printf("start\n");
int forkRet = fork();
if(forkRet == 0){
printf("child process %d\n", getpid());
} else {
printf("forkRet: %d parent process:%d\n", forkRet, getpid());
}
return 0;
}
실행 결과
start!
forkRet: 136 parent process: 135
child process 136
start!는 부모 프로세스에 의해 한 번 출력된다. 그리고 부모 프로세스가 fork()함수를 호출하면 반환값은 자식 프로세스의 PID인 136이 된다. 따라서 else 문으로 가서 forkRet 값과 본인(부모 프로세스)의 PID를 출력한다. 자식 프로세스는 부모 프로세스가 fork()함수를 호출한 시점에 생성되고, 반환값이 0이므로 첫 번째 조건문인 forkRet == 0을 만족한다. 본인(자식 프로세스)의 PID를 출력하고 종료된다.
프로세스 상태도
모든 프로세스는 CPU에 의해 생성되괴 소멸하는 과정을 거친다. 이 과정에서 프로세스는 생성(new), 준비(ready), 대기(waiting), 실행(running), 종료(terminated)라는 5가지 상태로 존재한다.
- 생성(new): 프로세스가 PCB를 가지고 있지만 OS로 부터 승인(admit)받기 전
- 준비(ready): OS로부터 승인받은 후 준비 큐에서 CPU 할당을 기다림
- 실행(running): 프로세스가 CPU를 할당받아 실행
- 대기(waiting): 프로세스가 입출력이나 이벤트 발생을 기다려야 해서 CPU 사용을 멈추고 기다림
- 종료(terminated): 프로세스 실행을 종료함
프로세스는 한 상태에서 다른 상태로 변화한다.
- 생성 -> 준비 : 생성 상태의 프로세스가 OS로부터 승인을 받아, 준비 상태의 프로세스가 모여 있는 자료구조인 준비 큐에 추가된다.
- 준비 -> 실행 : 준비 큐에 있는 프로세스 중 우선순위가 높은 프로세스가 디스패치되어 실행된다.
- 실행 -> 준비 : CPU 독점을 방지하기 위해 타임아웃 되어 준비 상태로 변경된다.
- 실행 -> 대기 : 입출력 또는 이벤트 때문에 대기 상태로 변경된다.
- 대기 -> 준비 : 입출력 또는 이벤트가 완료되어 준비 상태로 변경된다.
- 실행 -> 종료 : 실행 중인 프로세스가 정상적으로 끝나서 종료 상태로 변경된다.
용어 사전
- 승인(admit): CPU를 제외한 다른 자원이 준비되어 해당 프로세스가 준비 상태가 될 수 있도록 OS가 허락하는 것
- 디스패치(dispatch): 프로세스에 CPU 자원을 할당해 해당 프로세스가 준비 상태에서 실행 상태가 되는 것을 의미
멀티 프로세스와 멀티 스레드
멀티 프로세스, 멀티 스레드 개념을 이해하기 위해선 동시성, 병렬성을 알아야 한다.
동시성(concurrency)은 하나의 코어(싱글 코어)에서 여러 작업을 번갈아 가면서 처리하는 방식이다.
CPU는 한 번에 하나의 작업만 처리할 수 있어서 여러 작업을 조금씩 돌아가면서 처리한다. 하나의 CPU에서 여러 작업을 번갈아 가면서 처리하기 위해 처리 중인 작업을 교체하는 것을 컨텍스트 스위칭(context switching)이라고 한다.
병렬성(parallelism)은 CPU가 여러 개(멀티 코어) 있어서 각 CPU에서 각 작업을 동시에 처리하는 방식이다.
물리적인 시간 관점에서 동시에 여러 작업이 처리된다.
멀티 프로세스
응용 프로그램 하나를 여러 프로세스로 구성하는 것을 의미한다. 멀티 프로세스 환경에서는 한 프로세스가 죽어도 다른 프로세스에 영향을 주지 않는다. 그래서 응용 프로그램을 프로세스 하나로 구성하는 것보다 여러 개로 구성하는 것이 안정적이다.
그러나 시간과 메모리 공간을 많이 사용한다는 단점이 존재한다. CPU는 하나의 작업만 처리할 수 있다. 그래서 여러 프로세스를 처리하려면 CPU에서 처리 중인 프로세스를 교체하는 콘텍스트 스위칭이 이루어져야 한다. 이때 CPU에서 기존에 처리하던 프로세스가 할당받은 메모리 영역은 다른 프로세스에서 사용할 수 있게 교체하면서 시간과 메모리가 필요한데, 이를 오버헤드라고 한다.
프로세스는 독립적인 메모리를 할당받는다. 프로세스 간에 공유할 자원이 있다면 IPC(Inter Process Communication)을 통해 프로세스 간에 자원을 공유해야 한다. 공유할 메모리를 직접 참조하는 것보다 비효율적이다.
멀티 스레드
스레드를 여러 개 생성해 스레드들이 각자 다른 작업을 처리하는 것을 말한다. 멀티 스레드는 스레드 간에 힙, 데이터, 코드 영역을 공유한다. 콘텍스트 스위칭할 때 오버헤드가 적게 발생하고 IPC를 사용하지 않아도 되어 멀티 프로세스의 단점을 보완할 수 있다.
독립적인 메모리 공간을 갖는 프로세스를 여러 개 생성하는 것보다 스레드를 여러 개 생성하는 것이 자원을 효율적으로 사용할 수 있다.
스레드 간 자원 공유가 프로세스 간 자원 공유보다 시스템 처리 비용이 적고 프로그램 응답 시간도 단축된다.
그러나 스택 영역을 다른 스레드와 함께 사용하므로 공유 자원에 대한 동기화가 필수다. 스레드에 문제가 생기면 프로세스 내 다른 스레드에 영향을 미칠 수 있다.
2024/05/24
콘텍스트 스위칭
콘텍스트 스위칭을 이해하려면 인터럽트(interrupt)를 알아야 한다.
interrupt는 한국어로 '방해하다, 중단시키다'라는 뜻으로 CPU에서 프로세스를 처리하다가 입출력 관련 이벤트가 발생하거나 예와 상황이 발생할 때 이에 대응할 수 있게 CPU에서 처리를 요청하는 것이다. 인터럽트가 발생하는 경우는 입출력이 발생할 때, CPU 사용 시간이 만료되었을때, 자식 프로세스를 생성할 때가 있다.
CPU는 하나의 프로세스만 처리할 수 있으므로 멀티 프로세스를 처리하려면 CPU 스케줄러에 의해 인터럽트가 발생하면서 콘텍스트 스위칭이 이뤄진다. 콘텍스트(context)는 CPU가 처리하는 프로세스의 정보를 의미한다. 멀티 프로세스 환경에서 CPU가 처리 중인 프로세스의 정보를 바꾸는 것이 콘텍스트 스위칭이다.
처리 중인 프로세스를 P1, 다음에 처리해야 하는 프로세스를 P2라고 할때, CPU가 P1을 처리하던 중 운영체제에 의해 인터럽트가 발생한다. 그러게 되면 P1은 유휴 상태(idle)로 변하고 스케줄러는 레지스터에 있는 처리 중인 작업 정보를 P1의 PCB에 저장한다. 그리고 P2의 PCB에 있는 정보를 가져와 레지스터에 로드하고 CPU는 P2를 처리하기 시작한다.
P1의 정보를 PCB에 저장하고, P2의 PCB에 저장된 정보를 레지스터에 로드하는 동안 CPU는 아무 일도 못 하게 된다. 어떤 처리를 하는 데 간접적인 처리 시간과 메모리가 쇼요될 경우 '오버헤드가 발생한다'고 한다.
멀티 스레드를 처리할 때도 컨텍스트 스위칭이 이뤄진다. 멀티 프로세스의 컨텍스트 스위칭보다 시간과 메모리가 자원을 적게 사용한다.
멀티 스레드는 스택을 제외한 힙, 데이터, 코드 영역을 공유하므로 레지스터에 저장하고 로드해야 하는 데이터가 상대적으로 적기 때문이다.
CPU에서 처리중인 프로세스가 중간에 변경되어도 이전에 실행하던 코드를 이어서 실행할 수 있는 이유는 PCB 프로그램 카운터와 스택 포인터 값이 저장되어 있기 때문이다. 프로그램 카운터는 프로세스가 이어서 처리해야 하는 명령어의 주소값이고, 스택 포인터는 스택 영역에서 데이터가 채워진 가장 높은 주소 값 이어서 실행할 주소 값이 무엇인지, 데이터가 스택에 어디까지 채워져 있는지 알고 있으므로 콘텍스트 스위칭이 원활히 이뤄질 수 있다.
프로세스 동기화
경쟁 상태
여러 프로세스 또는 스레드에서 하나의 공유 자원에 접근하는 경우가 있는데, 자원에 접근하는 순서에 따라 결과 값이 달라질 수 있다. 이러한 현상을 공유 자원에 동시에 접근해 경쟁하는 상태라고 해서 경쟁 상태라고 한다.
경쟁 상태의 대표적인 예로 너무 많은 우유 문제(too much milk problem)이 있다.
냉장고 우유가 다 떨어져서 새로 사야하는 상황을 가정
1. 엄마가 냉장고를 열어 우유가 없는 것을 확인한다.
2. 엄마가 우유를 사러 슈퍼마켓에 간다.
3. 엄마가 우유를 사서 집에 돌아오는 길에 아빠가 냉장고에 우유가 없는 것을 확인한다.
4. 아빠가 우유를 사러 슈퍼마켓에 간다.
5. 아빠가 우유를 사서 집에 돌아온다.
우유는 1개면 충분하지만, 2개가 되어서 문제가 된다. 냉장고는 공유 자원, 엄마, 아빠는 각각 프로세스를 의미한다. 우유가 0개에서 1개가 되는 것을 기대했지만, 엄마가 우유를 사러 간지 모르고 아빠가 우유를 사러 감으로써 우유는 총 2개가 되는, 의도하지 않은 결과를 초래한다. 이러한 문제를 해결하기 위해선 프로세스 동기화가 이뤄져야 한다.
임계 영역
공유 자원에 접근할 수 있고 접근 순서에 따라 결과가 달라지는 코드 영역을 임계 영역이라고 한다. 냉장고에 우유 유무를 판단하고 우유를 추가하는 부분이 임계 영역에 해당한다. 임계 영역에서 경쟁 상태가 발생하는 것을 방지하려면 여러 프로세스가 공유 자원에 접근해도 데이터의 일관성이 유지되도록 프로세스 동기화를 해야한다.
임계 영역에 여러 접근이 동시에 발생하는 것을 방지하려면 3가지 조건을 충족
- 상호배제 기법(mutual exclusive): 어떤 프로세스가 임계 영역을 실행 중일 때 다른 프로세스가 임계 영역에 접근할 수 없다. 상호배제 기법으로는 뮤텍스와 세마포어가 있다.
- 진행(process): 임계 영역을 실행 중인 프로세스가 없을 때 다른 프로세스가 임계 영역을 실행한다.
- 한정된 대기(bounded waiting): 임계 영역에 접근을 요청했을 때 무한한 시간을 기다리지 않는다.
뮤텍스
락(lock)을 가진 프로세스만이 공유 자원에 접근할 수 있게 하는 방법이다.
개념을 이해하기 쉽도록 화장실 예를 살펴보기
뮤텍스의 작동 방식은 화장실과 화장실 열쇠가 하나뿐인 식당과 같다.
1. 식당에는 화장실 한 칸과 화장실 문을 열 수 있는 열쇠 한 개가 있다.
2. A가 열쇠를 가지고 화장실에 간다.
3. 화장실에 가려던 B는 열쇠가 없어서 기다린다.
4. A가 화장실에서 나와 열쇠를 반납하면, 기다리던 B가 열쇠를 가지고 화장실에 간다.
화장실은 공유 자원을 포함한 임계 영역을, 열쇠는 락을, A와 B는 공유 자원에 접근하려는 프로세스를 의미한다. 임계 영역에서 먼저 접근한 프로세스가 임계 영역에 락을 걸면 다른 프로세스들은 해당 프로세스가 락을 해제하기 전까지 대기해야 한다. 임계 영역에 접근한 프로세가 임계 영역에 락을 건다고 해서 락킹 매커니즘이라고도 한다.
임계 영역에 접근하지 못하는 프로세스는 락을 얻기 위해 기다리는 동안 락이 풀렸는지 반복문을 돌면서 확인한다. 이를 바쁜 대기의 한 종류인 스핀락이라고 한다. 스핀락은 락을 얻기 위해 프로세스가 반복문을 돌면서 기다리는 것을 의미한다. 프로세스가 대기 상태가 되지 않고 반복문을 돌면서 자원의 사용 가능 여부를 확인하므로 프로세스가 빠르게 교체될 수 있다.
바쁜 대기 : 프로세스가 공유 자원에 접근할 수 있는 권한을 얻을 때까지 확인하는 과정
2024/05/27
세마포어
공유 자원에 접근할 수 있는 프로세스의 수를 정해 접근을 제어하는 방법
세마포어의 작동 방법 화장실 비유
1. 식당에 화장실 3칸, 화장실을 열 수 있는 열쇠가 3개 있다.
2. A가 화장실 열쇠 하나를 가지고 화장실에 간다. 열쇠는 2개가 남는다.
3. B,C가 열쇠를 하나씩 가지고 화장실에 간다. 남은 열쇠가 없어서 D는 화장실에 가지 못한다.
4. C가 화장실에서 나와 열쇠를 돌려놓으면, D가 화장실에 간다.
화장실은 공유 자원을 포함한 임계 영역을 의미하고, A,B,C,D는 공유 자원에 접근 하려는 프로세스를 의미한다.
화장실 개수(열쇠 개수)는 공유 자원에 접근할 수 있는 프로세스의 수를 제어하기 위한 정수 변수를 나타낸다. 임계 영역에 접근할 수 있는 키 n개를 지정하고 이 중 하나를 가진 프로세스만 이 임계 영역에 접근하게 하는 방식이다. 이 방식은 공유 자원에 접근한 프로세스가 접근을 해제하면 다른 프로세스가 접근할 수 있도록 신호를 보낸다고 해서 시그널링 매커니즘이라고도 한다.
하나 더 알기
동기와 비동기, 블로킹과 넌블로킹
동기와 비동기는 작업 순서에 대한 개념이고, 블로킹과 넌블로킹은 작업을 위한 대기를 구분하는 개념이다.
- 동기(synchronization): 여러 작업을 처리할 때 순서를 보장한다.
- 비동기(asynchronization): 여러 작업을 처리할 때 작업 순서를 보장하지 않는다.
- 블로킹(blocking): 작업을 수행할 때 대기할 수 있다는 것을 의미하며 작업 순서를 보장하지 않는다.
- 넌블로킹(non-blocking): 작업을 시작하면 대기 없이 수행한다는 것을 의미한다.
교착 상태
상호배제 기법 때문에 2개 이상의 프로세스가 각각 자원을 가지고 있으면서 서로의 자원을 요구하며 기다리는 상태를 교착 상태라고 한다.
교착 상태가 발생하는 4가지 필요 충분 조건
- 상호배제(mutual exclusion): 하나의 공유 자원에 하나의 프로세스만 접근
- 점유와 대기(hold and wait): 프로세스가 최소 하나의 자원을 점유하고 있는 상태에서 추가로 다른 프로세스에서 사용 중인 자원을 점유하기 위해 대기한다.
- 비선점(non-preemption): 다른 프로세스에 할당된 자원을 뺏을 수 없다.
- 환형 대기(circular wait): 프로세스가 자신의 자원을 점유하면서 앞이나 뒤에 있는 프로세스의 자원을 요구한다.
교착 상태를 막으려면 앞의 4가지 필요 충분 조건 중에서 한가지를 제거하면 된다.
- 상호배제 부정: 여러 프로세스가 동시에 하나의 공유 자원을 사용할 수 있게 한다.
- 점유와 대기 부정: 프로세스가 실행되기 전에 필요한 모든 자원을 할당함으로써 프로세스 대기를 없앤다. 또는 프로세스가 자원을 점유하지 않은 상태에서만 자원을 요구하게 된다.
- 비선점 부정: 자원을 점유한 프로세스가 다른 자원을 요구할 때 점유한 자원을 반납하게 한다.
- 환형 대기 부정: 자원을 선형 순서로 정렬해 고유 번호를 할당한다. 각 프로세서에서 요구할 수 있는 번호의 방향을 정해서 한쪽 방향으로만 자원을 요구하게 된다.
2024/05/30
하나더 알기
교착 상태의 필요 충분 조건은 외우지 않고 이해하는 것이 좋다. 각 프로세스를 사람이라고 생각하면 이해하기 쉽다.
아래 그림은 프로세스 1이 자원 1을, 프로세스 2가 자원 2를 가지고 있는 상황이다. 프로세스 1은 자원 2가 필요하고, 프로세스 2는 자원 1이 필요해 교착 상태가 발생한다.
상호배제는 하나의 공유 자원에 대해 하나의 프로세스만 사용할 수 있다는 개념, 만약 하나의 공유 자원을 여러 프로세스가 공유할 수 있다면위 그림을 성립할 수 없다. 자원을 공유할 수 있게 되면 서로의 자원을 기다리는 상황을 에방할 수 있다.
점유와 대기는 하나의 프로세스가 이미 자원을 가진 상태에서 다른 프로세스의 자원을 갖기 위해 기다리는 상황, 프로세스가 자원을 요구할 때 필요한 자원 1과 자원 2를 모두 주거나 가진 자원이 없는 경우에만 자원을 할당함으로써 문제를 해결할 수 있다.
비선점은 다른 프로세스가 가지고 있는 자원을 뺏을 수 없다는 개념이다. 프로세스 1이 프로세스 2의 자원을 뺏을 수 있게 한다면 서로의 자원을 갖기 위해 대기하는 상황을 예방할 수 있다.
환형 대기는 프로세스 1이 프로세스 2의 자원을 요구하고, 프로세스 2가 프로세스 1의 자원을 요구함으로써 생긴다. 각자의 자원을 가진 상태에서 상대방의 자원을 요구하는 상황이다. 작은 번호 프로세스가 큰 번호 프로세스의 자원을 요구하는 것만 가능하게 한다면 프로세스 2가 프로세스 1의 자원을 요구할 수 없게 되므로 환형 대기를 없앨 수 있다.
스레드의 안전
스레드 안전은 멀티 스레드 환경에서 하나의 변수, 함수, 객체에 스레드 여러 개가 동시에 접근해도 문제가 없음을 의미한다.
스레드가 안전하지 않은 경우는 다음과 같이 간단한 코드에서도 나타난다.
var++;
var변수의 값을 메모리에서 CPU 레지스터로 로드 >> 연산 처리 >> 연산 결과를 메모리에 작성하는 과정을 거치게 된다. 이 코드에 스레드 2개가 접근하면 잘못된 결과를 초래할 수 있다.
한 줄 짜리 코드에서도 스레드 2개가 접근하면 예상 밖의 결과가 나온다.
1.2.7 프로세스 동기화에서 이야기한 너무 많은 우유 문제도 스레드 안전하다고 할 수 없다.
깊게 알기 [스레드 안전을 위한 조건]
상호배재(mutual exclusive) : 공유 자원에 접근해야 할 때 뮤텍스 또는 세마포어와 같은 상호배제 기법을 사용해서 접근을 통제
원자 연산(atomic operation): 공유 자원에 접근할 때 원자 연산을 이용하거나 원자적으로 정의된 연산을 이용해 도중에 다른 스레드가 접근할 수 없게 한다. 원자연산이란 '연산했다'와 '연산 안 했다' 두 가지만 존재하는 연산이다.
재진입성(reentrancy): 특정 함수를 하나의 스레드에서 실행 중일 때 다른 스레드가 해당 함수를 실행해도 각 스레드에 올바른 결과가 나올 수 있게 해야 한다.
스레드 지역 저장소(thread local storage): 각 스레드에서만 접근할 수 있는 저장소를 사용해서 공유되는 자원을 줄여야 한다.
IPC
프로세스는 고유한 메모리 영역을 갖기 때문에 프로세스 간 자원을 공유해야 할 때 IPC해야 한다.
IPC는 Inter Process Communication의 약자로, 프로세스 간에 자원을 공유하는 방식을 나타낸다.
1. 공유 메모리(shared memory)
프로세스 간에 공유 가능한 메모리를 구성해 자원을 공유하는 방식이다. 여러 프로세스에서 접근할 수 있으므로 동기화 문제가 발생할 수 있다.
2. 소켓(Socket)
네트워크 소켓을 이용하는 프로세스 간 통신으로, 외부 시스템과도 이용할 수 있다. 클라이언트와 서버 구조로 자원을 주고받는다.
3. 세마포어(semaphore)
접근하는 프로세스를 제어해 공유 자원을 관리한다.
4. 파이프(pipe)
FIFO(First In First Out) 형태의 메모리인 파이프를 이용해 프로세스 간 자원을 공유하는 방식이다. 파이프는 단방향 통신만 지원하므로 읽기 또는 쓰기 중 하나만 할 수 있다. 양방향 통신을 하려면 읽기 파이프(read pipe)와 쓰기 파이프(write pipe)를 각각 생성해야 한다.
5. 메시지 큐(message queue)
FIFO 형태의 큐 자료구조를 이용해 프로세스 간 메시지를 주고받는 방식이다.
좀비 프로세스와 고아 프로세스
자식 프로세스가 종료되었지만 부모 프로세스가 자식 프로세스의 종료 상태를 회수하지 않았을 경우에 남겨진 자식 프로세스를 좀비 프로세스라고 한다. 자식 프로세스가 종료될 때 부모 프로세스에 SIGCHLD라는 시그널을 보내면 부모 프로세스에서 wait() 함수(시스템 콜)를 호출해 자식 프로세스의 상태 정보를 받고 자원을 회수한다. 자원 회수에 실패하면 좀비 프로세스가 생기게 된다. 좀비 프로세스가 쌓이면 자원이 낭비될 수 있다.
부모 프로세스가 자식 프로세스보다 먼저 종료되는 경우에 자식 프로세스를 고아 프로세스라고 한다. 이럴 때는 자식 프로세스의 부모 PID를 init 프로세스(부팅 시 가장 먼저 실행되는 프로세스)의 PID인 1로 바꿔 준다. 이렇게 하면 고아 프로세스의 부모 프로세스는 init 프로세스가 된다. 이후에 고아 프로세스가 작업을 종료하면 init 프로세스가 고아 프로세스의 자원을 회수해 좀비 프로세스가 되는 것을 방지할 수 있다.
스케줄링
멀티 프로세스 환경에서는 여러 프로세스가 모두 실행되어야 하지만, CPU 자원은 한정적이다. 그래서 스케줄링을 통해 모든 프로세스를 공평하게 실행해 한정된 자원을 효율적으로 활용하는 것이 OS의 주 목적이다. OS에서 스케줄링은 빠질 수 없는 개념으로 목적, 단계, 각종 용어를 숙지해야 한다.
스케줄링의 목적
스케줄링의 주도니 목적은 멀티 프로세서 환경에서 모든 프로세스를 공평하게 실행하는 것이다.
- 공평성 : 모든 프로세스가 공평하게 실행되어야 한다. 특정 프로세스가 실행되지 않는 경우가 없도록 스케줄링해야 한다.
- 효율성 : 자원을 효율적으로 사용해 자원이 사용되지 않는 시간이 없도록 스케줄링해야 한다.
- 안전성 : 우선순위를 고려해 높은 우선순위의 프로세스를 먼저 처리하도록 스케줄링해야 한다.
- 반응 시간 보장: 프로세스가 오랜 시간 응답이 없으면 사용자는 시스템이 멈춘 것으로 보기 때문에 일정 시간 내에 응답할 수 있도록 스케줄링 해야 한다.
2024/06/04
스케줄링의 단계
스케줄링은 장기 스케줄링, 중기 스케줄링, 단기 스케줄링으로 나뉜다.
- 장기 스케줄링(long-term scheduling): 준비 큐에 어떤 프로세스를 넣을지 결정해 메모리에 올라가는 프로세스 수를 조절한다. 잡 스케줄링 또는 승인 스케줄링이라고도 한다. 현대 운영체제에서는 시분할 시스템을 사용하기 때문에 대부분 사용 x
- 중기 스케줄링(mid-term scheduling): 메모리에 로드된 프로세스 수를 동적으로 조절한다. 메모리에 프로세스가 많이 로드되면 스왑 아웃해서 일부 프로세스를 통째로 저장한다. 스왑 아웃된 프로세스는 중단 상태가 된다. 중단 상태는 준비 상태에서 스왑 아웃된 '중단된 준비 상태'와 대기 상태에서 스왑 아웃된 '중단된 대기 상태'로 구분된다.
- 단기 스케줄링(short-term scheduling): 준비 큐에 있는 대기 상태 프로세스 중 어떤 프로세스를 다음으로 실행할지 스케줄링 알고리즘으로 결정한다. 어떤 프로세스를 디스패치할지 결정하는데, 이를 CPU스케줄링이라고도 한다.
스케줄러 관점에서 프로세스 스케줄링을 표현하면 다음 그림과 같다.
(1) 스케줄러가 준비 큐에 있는 프로세스 중 하나를 선택해 CPU에 디스패치한다. 스케줄링 알고리즘을 이용한다.
(2) CPU에서 프로세스를 실행한다. 프로세스는 실행 상태이다.
(A) 프로세스 수행이 완료되면 프로세스를 종료한다.
(B) 일정 시간을 초과하면 인터럽트가 발생해 프로세스가 준비 큐로 들어가고 준비 상태가 된다.
(C) 입출력 요청이 들어오면 인터럽트가 발생한다. 프로세스는 대기 큐로 들어가서 대기 상태가 된다. 입출력이 완료되면 프로세스는 준비 큐로 들어간다.
(3) fork()가 호출되면 자식 프로세스가 생성되고, 자식 프로세스는 준비 큐로 들어간다.
하나 더 알기
스왑 아웃(swap out): 프로세스가 실행되려면 메모리에 로드되어야 한다. 메모리 공간보다 많은 프로세스가 로드되는 경우가 존재한다. 이때 중기 스케줄러가 이벤트 발생을 기다리고 있는 프로세스를 통째로 저장 공간(SSD와 같은 영역)으로 옮겨 저장하는 것
스왑 인(swap in): 스왑 아웃한 프로세스에서 이벤트 요청이 오면 해당 프로세스를 통째로 다시 메모리에 로드하는 것
스와핑(swapping): 스왑 아웃과 스왑 인처럼 프로세스를 통째로 메모리 영역과 저장 공간으로 옮겨 가는 것. 스와핑 하면 메모리 공간보다 많은 프로세스를 실행할 수 있다는 장점이 있다.
스케줄링 알고리즘
CPU 스케줄러(단기 스케줄러)가 준비 큐에 있는 프로세스 중 어떤 프로세스를 실행시킬지 결정하는 데 사용한다. 스케줄링 알고리즘은 슼케줄링의 목적을 달성하기 위해 다음과 같은 기준으로 평가한다. 하지만 이를 모두 만족하기는 어려우므로 어떤 기준을 더 중요하게 여길지 판단해야 한다.
- CPU 사용률: CPU를 놀리지 않고 사용하는지 판단
- 처리량: 단위 시간(time unit)당 실행한 프로세스 수
- 응답 시간: 프로세스에 요청이 발생했을 때 응답까지 걸리는 시간
- 반환 시간: 프로세스가 로드된 이후부터 종료될 때까지 걸리는 시간
- 대기 시간: 프로세스가 대기 큐에서 대기하는 시간의 총합
스케줄링 알고리즘은 비선점형과 선점형으로 나뉜다.
비선점형 스케줄링
실행 중인 프로세서가 종료될 때까지 다른 프로세스를 실행할 수 없음을 의미한다. 해당 알고리즘으로는 FCFS(First Come First Served) 스케줄링, SJF(Shortest Job First) 스케줄링, HRRN(Highest Response Ratio Next) 스케줄링이 있다.
FCFS 스케줄링: 준비 큐에 먼저 들어온 프로세스가 우선순위를 갖는 알고리즘이다. 준비 큐에 먼저 들어온 프로세스(first come)를 먼저 실행(first served)한다.
SJF 스케줄링: 실행 시간이 짧은 프로세스가 우선순위를 갖는 알고리즘으로, SJN(Shortest Job Next) 스케줄링이라고도 한다.준비 큐에 있는 프로세스 중 CPU를 점유하는 실행시간이 가장 짧은 프로세스(shortest job)부터 실행한다. 평균 대기 시간이 가장 짧지만, 실행 시간이 긴 프로세스는 실행 시간이 짧은 프로세스에 밀려 기아 상태가 될 수 있다.
용어 사전
기아 상태(starvation): 프로세스마다 우선순위가 있는데, 우선순위가 높은 프로세스만 수행되어 우선순위가 낮은 특정 프로세스는 계속 실행되지 못하는 것을 의미
선점형 스케줄링
스케줄러가 실행 중인 프로세스를 중단시키고 다른 프로세스를 실행할 수 있음을 의미한다. 해당 알고리즘으로는 RR(Round Robin) 스케줄링, SRTF(Shortest Remaining Time First)스케줄링, 멀티 레벨(multi level)스케줄링이 있다.
2024/06/05
RR 스케줄링 : 비선점형 스케줄링과 달리 프로세스 간 우선순위가 없다. 프로세스를 순서대로 일정 시간 동안 실행하며, 일정 시간을 초과하면 다른 프로세스를 실행한다. 일정 시간은 '시간 단위'를 의미하며 타임 퀀텀(time quantum) 또는 타임 슬라이스(time slice)라고 한다. 일반적으로 시간 단위는 10~100밀리초다. 콘텍스트 스위칭이 빈번하게 일어나서 오버헤드가 크다는 단점이 있지만, 모든 프로세스가 반복 수행되어 응답 속도가 빠르다는 장점도 있다.
SRTF 스케줄링 : 준비 큐에서 대기 시간이 가장 짧게 남은 프로세스를 우선 수행하는 알고리즘이다. 한 프로세스가 실행 중일 때 실행 시간이 더 짧은 프로세스가 준비 큐에 들어오면 실행 시간이 더 짧은 프로세스가 CPU를 차지하게 된다. 평균 대기 시간이 짧다는 장점이 있지만, 수행 시간이 긴 프로세스는 기아 상태가 되기 쉽다.
멀티 레벨 스케줄링 : 준비 큐를 목적에 따라 여러 개로 분리해 사용하는 알고리즘이다. 분리한 큐는 각각 우선순위가 있고 각자 다른 스케줄링 알고리즘을 적용할 수 있다. 여러 개의 큐는 foreground 큐와 background 큐로 나뉜다. foreground 큐에는 응답 속도가 중요한 프로세스가 들어가고, background 큐에는 응답 속도보다 성능을 중요시하는 프로세스가 들어간다.
스케줄링 예제
프로세스 이름 | 예상 실행 시간 | 준비 큐에 들어온 시간 |
P1 | 150 | 0 |
P2 | 60 | 20 |
P3 | 300 | 40 |
P4 | 270 | 60 |
P5 | 120 | 80 |
FCFS 스케줄링에서 각 프로세스의 실행 순서
평균 대기 시간은 각 프로세스의 대기 시간을 합한 뒤 프로세스의 수로 나눈 것과 같다. FCFS의 평균 대기 시간은 290이 된다.
SJF 스케줄링에서 각 프로세스의 실행 순서
같은 방법으로 계산하면 SJF 스케줄링에서 평균 대기 시간은 218로, FCFS 스케줄링 알고리즘보다 짧다.
RR 스케줄링에서 각 프로세스의 실행 순서
RR 스케줄링에서 어떤 프로세스에 응답 요청이 들어 왔을 때 기다리는 최대 시간은 (전체 프로세스 수) - 1에 (시간 단위)를 곱한 값이다.
ex) 200밀리초 안에 응답할 수 있다.
응답 속도가 다른 스케줄링보다 빠르지만, 콘텍스트 스위칭이 빈번하게 일어나므로 시간 단위를 적절하게 설정해야 한다.
SRTF 스케줄링에서 각 프로세스의 실행 순서
프로세스가 중간에 중단된 경우에는 수행 완료까지의 대기 시간을 합하면 된다. >> 202
다른 스케줄링 알고리즘보다 평균 대기 시간이 짧은 것을 알 수 있다. P3가 P4보다 준비 큐에 빨리 들어왔어도 실행 시간이 길어서 마지막 순서로 밀렸듯이 실행 시간이 긴 프로세스는 기아 상태가 되기 쉽다.
멀티 레벨 스케줄링은 준비 큐가 목적에 맞춰 여러 큐로 나뉘어 있다. 프로세스가 들어오면 해당 프로세스의 우선순위에 맞는 큐가 들어가서 대기하게 된다.
연속 메모리 할당
멀티 프로세스 환경에서 여러 프로세스를 메모리에 연속적으로 로드하는 방법이다.
연속 메모리 할당 방법은 2가지 방식이 존재한다.
고정 분할 방식
고정 분할을 메모리 영역을 분할한 뒤 각 영역에 프로세스를 할당하는 방식이다. 분할된 영역의 크기는 서로 다를 수 있으며, 분할된 크기는 고정된다. 이 방식은 메모리에 올릴 수 있는 프로세스 수와 각 프로세스 크기가 제한된다는 단점이 있고, 단편화 문제가 발생할 수 있다.
8MB의 메모리 공간과 2MB의 메모리 공간을 합치면 프로세스 7에 공간을 할당할 수 있지만, 고정 분할 때문에 할당하지 못한다. 이런 경우를 외부 단편화라고 한다. 프로세스 3과 프로세스 4처럼 분할된 크기보다 작은 프로세스가 할당되어 메모리 공간이 남는 경우를 내부 단편화라고 한다.
가변 분할 방식
할당할 프로세스의 크기에 따라 메모리 공간을 분할하는 방식이다. 메모리 할당 알고리즘을 이용해 가용 메모리 공간에서 프로세스가 로드될 수 있는 메모리 공간을 찾는다. 메모리 할당 알고리즘으로는 최초 적합, 최적 적합, 최악 적합 등이 있다.
1. 최초 적합(first-fit)
가용 메모리 공간에서 프로세스 크기만큼 비어 있는 메모리 공간을 찾아 차례대로 프로세스를 로드하는 방식이다.
(1) 20MB의 프로세스 1이 56MB의 가용 메모리 공간에 할당된다.
(2) 18MB의 프로세스 2가 36MB 가용 메모리 공간에 할당된다.
(3) 12MB의 프로세스 3이 18MB 가용 메모리 공간에 할당된다.
(4) 메모리 영역에서 프로세스 2의 할당이 해제된다.
(5) 6MB의 프로세스 4를 할당할 수 있는 가용 메모리 공간을 찾으면 가장 먼저 18MB의 메모리 공간이 탐색된다. 그런 경우 더 이상 탐색을 진행하지 않고 프로세스 4를 해당 메모리 공간에 할당한다.
2024/06/11
2. 최적 적합(best-fit)
할당하려는 프로세스 크기 이상인 가용 메모리 공간 중에서 가장 작은 공간에 프로세스를 할당하는 방식
이 방식은 가용 메모리 공간을 모두 탐색해야 한다.
(1) 20MB의 프로세스 1이 56MB의 가용 메모리 공간에 할당된다.
(2) 18MB의 프로세스 2가 36MB의 가용 메모리 공간에 할당된다.
(3) 12MB의 프로세스 3이 18MB의 가용 메모리 공간에 할당된다.
(4) 메모리 영역에서 프로세스 2의 할당이 해제된다.
(5) 6MB의 프로세스 4를 할당할 수잇는 가용 메모리 공간을 찾으면 18MB와 6MB의 공간이 탐색된다. 가장 작은 6MB 메모리 공간에 프로세스 4가 할당된다.
3. 최악 적합(worst-fit)
할당하려는 프로세스 크기보다 큰 가용 메모리 공간 중에서 가장 큰 공간에 프로세스를 할당하는 방식
최적 적합 방식과 마찬가지로 가용 메모리 공간을 모두 탐색
(1) 20MB의 프로세스 1이 56MB의 가용 메모리 공간에 할당된다.
(2) 18MB의 프로세스 2가 36MB의 가용 메모리 공간에 할당된다.
(3) 12MB 프로세스 3이 18MB 가용 메모리 공간에 할당된다.
(4) 메모리 영역에서 프로세스 2의 할당이 해제된다.
(5) 6MB의 프로세스 4를 할당할 수 있는 가용 메모리 공간을 찾으면 18MB와 6MB의 공간이 탐색된다. 이 중 가장 큰 18MB의 메모리 공간에 프로세스 4가 할당된다.
하나 더 알기
외부 단편화 문제를 해결하는 방법으로 메모리 압축이 있다. 메모리 압축은 프로세스가 사용 중인 메모리 공간을 재배치해서 흩어져 있는 가용 메모리 공간을 하나로 합치는 것으로, 메모리 집약이라고도 한다. 그림을 보면 흩어져 있는 가용 메모리 공간 중에서 프로세스 7이 들어갈 수 있는 공간은 없다. 메모리 압축을 수행하면 14MB의 가용 공간이 생긴므로 외부 단편화 문제를 해결하고 프로세스 7을 로드할 수 있다.
비연속 메모리 할당
비연속 메모리 할당은 프로세스의 메모리 영역을 나눠서 메모리 공간에 저장하는 방법으로, 페이징과 세그먼테이션이라는 2가지 방식이 있다.
페이징
프로세스의 논리 메모리 영역과 물리 메모리 영역을 각각 일정한 크기의 페이지와 프레임으로 나눈다. 페이지와 프레임 크기는 동일하다. 페이지와 프레임에는 각각 번호를 할당해 프로세스의 페이지와 메모리의 프레임을 매핑한다.
페이지와 프레임을 매핑하는 데는 페이지 테이블을 사용한다. 페이지 테이블을 프로세스의 페이지 정보와 페이지에 매핑하는 프레임의 주소 값을 저장한다. 페이지 테이블은 각 프로세스의 PCB에 저장된다.
페이징 기법을 사용하면 페이지를 물리 메모리에 연속 할당할 필요가 없어서 외부 단편화 문제를 해결할 수 있다.
프로세스 크기가 페이지 수로 나누어 떨어지는지는 보장하지 않는다. 그래서 프로세스의 마지막 페이지가 페이지 크기보다 작을 수 있으므로 내부 단편화 문제가 발생할 수 있다. 페이지 테이블을 저장하기 위한 메모리 공간이 추가로 필요하다.
하나 더 알기
페이징 기법엔는 3가지가 있다.
- 계층적 페이징(hierachical paging): 페이지 테이블을 다시 페이지로 나눠 페이지 테이블 자체를 페이징 하는 방식으로, 레벨 페이징이라고도 한다.
- 해시 페이지 테이블(hashed page table): 해시 테이블의 각 항목에 저장된 연결 리스트에 페이지 번호를 해싱한 뒤에 첫 번째 요소와 가상 페이지 번호를 비교하는 방식
- 역 페이지 테이블(inverted page table): 프레임을 이용해 페이지를 찾는 방식이다. 페이지로 프레임을 찾는 기존 방식과 반대다
세그먼테이션
프로세스의 메모리 영역을 논리적 단위인 세그먼트로 분할해 메모리를 할당한다. 논리적 단위는 파일 내 함수 단위나 프로세스의 스택, 힙과 같은 영역을 의미하기도 한다.
세그먼테이션 테이블을 사용해 세그먼트의 논리 주소를 물리 주소로 매핑한다. 세그먼트 테이블은 세그먼트 번호를 인덱스로 사용하며, 세그먼트별 시작 주소인 base와 세그먼트 길이인 limit를 저장한다.
프로세스의 메모리 영역을 논리적 단위로 나눠 저장하므로 단위별로 데이터를 보호하기 쉽다는 장점이 있다. 세그먼트의 크기가 균등하지 않아서 프로세스의 할당/해제를 반복하는 과정에서 외부 단편화 문제가 발생할 수 있다. 메모리에 로드된 스택 세그먼트 영역에서 오버플로가 발생하면 다른 프로세스와 메모리 영역이 겹칠 수 있다. 그러면 다른 프로세스의 세그먼트나 스택 오버플로가 발생한 세그먼트를 디스크로 스왑 아웃해야 하는 단점이 있다.
가상 메모리
사용자가 프로그램을 실행하면 OS는 디스크에 저장된 데이터를 메모리로 로드한다. 메모리 공간은 한정되어 있고, 사용자는 동시에 많은 프로그램을 실행하고 싶어 한다. 이런 메모리 공간의 한계를 극복하기 위해 가상 메모리라는 개념이 등장!
가상 메모리란
가상 메모리는 프로세스의 일부만 메모리에 로드하고, 나머지는 디스크에 둔 상태로 프로세스를 실행하는 방식이다. 이 방식은 프로세스 전체가 메모리에 올라오지 않아도 프로세스를 실행하는 데 문제가 없다는 점에서 착안했다. 사용자에게는 프로세스 전체가 메모리에 로드된 것처럼 보이지만, 실제로는 전체가 로드된 것이 아니어서 가상 메모리라고 한다.
그림처럼 메모리에 프로세스 일부를 로드하고, 프로세스의 나머지 영역은 디스크에 두면 더 많은 프로세스를 메모리에 로드할 수 있다.
가상 메모리를 사용할 때 장점
- 프로그램이 메모리 크기에 대한 제약을 받을 수 있다.
- 동시에 많은 프로그램을 실행하므로 CPU이용률과 처리율을 높일 수 있다.
- 필요한 영역만 메모리에 로드해 스와핑 횟수를 줄여서 프로그램 실행 속도를 높일 수 있다.
메모리 스와핑 : 메모리에 현재 사용되지 않는 프로세스가 있을 경우 해당 프로세스의 메모리를 임시 보조 기억장치로 옮겨 두는 것을 말한다.
요구 페이징
프로세스에서 필요한 페이지만 메모리에 로드하는 방식 페이지를 모두 메모리에 로드하지 않고 초기에 필요한 영역만 로드한 후 다른 여역은 요청이 올 때 메모리에 로드한다.
필요한 페이지를 물리 메모리에 로드하고, 필요하지 않은 페이지는 디스크에 저장한다.
프로그램을 실행하다가 물리 메모리에 필요한 페이지가 없을 때 이를 페이지 폴트라고 한다. 페이지 폴트가 발생하면 디스크에서 필요한 페이지를 스왑 인한다. 페이지에 해당하는 메모리 영역이 물리 메모리에 있는지는 페이지 테이블로 파악할 수 있다. 페이지 테이블은 페이지에 해당하는 프레임이 존재하면 v(valid)값을 프레임이 존재하지 않거나 유효하지 않은 주소 값이면 i(Invalid) 값을 반환한다.
페이지 폴트가 발생했을 때 처리 과정
(1) 필요한 페이지가 물리 메모리에 있는지 없는지를 페이지 테이블에서 확인한다. 페이지 폴트가 발생하면 i를 반환한다.
(2) i를 반환하면 OS는 참조하려는 페이지의 주소 값이 유효하지 않은지 아니면 메모리에 로드되지 않은 영역인지 판단한다.
(3) 필요한 페이지가 메모리에 로드되지 않은 영역이라면 디스크에서 해당 영역을 찾는다.
(4) 디스크에서 해당 페이지 영역을 스왑 인한다. 물리 메모리에 비어 있는 프레임이 있으면 페이지를 해당 영역에 바로 로드한다. 비어 있는 프레임이 없으면 페이지 교체 알고리즘을 호출해 기존에 로드된 페이지를 디스크로 스왑 아웃한 후 새로운 페이지를 로드한다.
(5) 페이지 테이블에서 새로 로드한 페이지의 값을 v로 변경한다.
(6) 프로세스를 다시 실행한다.
스레싱
동시에 일정 수 이상의 프로그램을 실행했을 때 오히려 CPU 이용률이 떨어지는 상황을 말한다.
가상 메모리를 구현해 다중 프로그래밍을 하면 CPU 이용률이 높아진다.
다중 프로그래밍이란? CPU 작업과 입출력 작업을 병행하는 것이다.
일정 수 이상으로 다중 프로그래밍을 하면 페이지 폴트가 자주 일어난다. 따라서 디스크 영역에서 필요한 페이지를 스왑 인하고 불필요한 페이지를 스왑 아웃하는 작업도 자주 하게 된다. 다중 프로그래밍 정도가 일정 수준 이상 높아지면 페이징이 빈번히 일어나게 되고 실질적으로 CPU 이용률이 떨어지는 스레싱이 발생한다.
스레싱을 예방하려면 워킹 세트를 설정하는 방법이 있다. 워킹 세트는 지역성을 기반으로 자주 사용하는 페이지를 저장해 두는 것을 의미한다. 워킹 세트를 바탕으로 자주 사용하는 페이지를 물리 메모리의 프레임에 고정하면 페이지 폴트가 빈번하게 발생하는 현상을 방지할 수 있다.
캐시 메모리
cpu는 메모리에 접근해 많은 데이터를 처리한다. 이때 시간을 줄이기 위해 자주 사용하는 데이터를 임시로 캐시 메모리에 저장한다.
캐시 메모리와 지역성
캐시 메모리는 CPU와 메인 메모리 간에 데이터 접근 시 속도 차이를 줄이기 위해 사용한다. CPU에서 메인 메모리에 있는 데이터를 가져올 때 자주 사용하는 데이터는 캐시 메모리에 따로 저장한다. 이후 해당 데이터가 필요하면 캐시 메모리에 접근한다. 이러면 메인 메모리에 접근하는 것보다 속도를 향상시킬 수 있다.
캐시 메모리에 어떤 데이터를 저장할지는 지역성을 바탕으로 결정한다. 지역성은 CPU가 자주 참조하는 데이터가 고르게 분포되지 않고 특정 부분에 몰려 있는 것을 나타낸다. 캐시 적중률을 높이려면 지역성을 바탕으로 데이터를 저장해야 한다.
지역성은 2가지 존재
- 시간 지역성(time locality): 최근 참조한 내용을 다시 참조할 가능성이 높다.
- 공간 지역성(space locality): 실제 참조한 주소 근처의 내용을 참조할 가능성이 높다.
캐시 메모리의 매핑 방식
- 직접 매핑 : 메인 메모리를 일정한 크기로 나누고 각 영역을 캐시 메모리에 매핑하는 방식, 메인 메모리는 캐시 메모리보다 크므로 나눠진 n개의 메모리 영역이 1개의 캐시 메모리에 매핑된다.
- 연관 매핑: 메모리 영역을 캐시 메모리에 규칙 없이 매핑하는 방식이다. 메모리 영역을 캐시 메모리에 적재할 때는 간단하지만, 캐시 메모리에서 필요한 메모리 영역을 찾을 때는 비효율적이다.
- 집합 연관 매핑: 직접 매핑과 연관 매핑을 결합해 단점을 보완한 방식으로, 범용적으로 사용된다.
면접 전 요약 정리
1. 메모리 계층 구조
(1) 사용 목적에 따라 메모리를 여러 계층으로 둠
(2) 레지스터, 캐시 메모리, RAM, 하드 디스크로 구성
(3) CPU 접근 속도 : 레지스터 > 캐시 > RAM > 하드 디스크
2. 시스템 콜
(1) 운영체제의 커널 모드에 접근해 필요한 기능을 수행하기 위해 프로세스에서 호출하는 함수
(2) 프로세스 제어, 파일 조작, 장치 조작 등을 수행
3. 프로세스
(1) 실행 중인 하나의 프로그램으로, 하나 이상의 스레드르 가짐
(2) PCB(Process Control Block)에 프로세스의 현재 상태, PID(ProcessID), 부모 PID 등을 저장한다.
(3) 프로세스마다 독립된 메모리 공간을 가짐
- 스택: 지역 함수 ,함수의 매개변수, 반환 주소 값 지정
- 힙: 동적 메모리 할당
- 데이터: 전역 변수, 정적 변수, 배열, 구조체 저장, 세부적으로 초기화된 데이터는 데이터 영역에, 초기화되지 않은 데이터는 BSS 영역에 저장
- 코드: 기계어
4. 스레드
(1) 프로세스에서 실제 실행되는 흐름의 단위
(2) 각 스레드는 스택 영역을 할당받는다.
(3) 스택을 제외한 영역은 다른 스레드와 공유
5. 멀티 프로세스와 멀티 스레드
(1) 멀티 프로세스
- 응용 프로그램을 여러 개의 프로세스로 구성하는 것
- 프로그램을 하나의 프로세스로 구성하는 것보다 안정적
- 콘텍스트 스위칭으로 오버헤드 발생
- 독립된 메모리 공간을 갖기 때문에 IPC를 사용
(2) 멀티 스레드
- 스레드를 여러 개 생성해 작업을 처리하는 것
- 스택을 제외한 영역은 다른 스레드와 공유하므로 데이터 동기화 필요
- 콘텍스트 스위칭 시 멀티 프로세스 대비 오버헤드가 적음
6. 콘텍스트 스위칭
(1) 멀티 프로세스 환경에서 CPU가 다른 프로세스를 처리하기 위해 처리중인 프로세스를 변경하는 것
(2) 처리하던 프로세스 정보를 저장하고, 다음으로 처리할 프로세스 정보를 레지스터에 로드하면서 오버헤드 발생
7. 프로세스 동기화
(1) 멀티 프로세스 환경에서 공유 자원의 일관성을 보장하기 위한 방법
(2) 상호배제 기법 이용
- 뮤텍스: 락(lock)을 가진 한 프로세스만 임계 영역에 접근 가능
- 세마포어: 정해진 개수의 프로세스만 임계 영역에 접근 가능
8. 교착 상태
(1) 상호 배제: 하나의 공유 자원을 한 개의 프로세스만 사용할 수 있다.
(2) 점유와 대기: 프로세스가 최소 하나의 자원을 점유하고 있는 상태에서 추가로 다른 프로세스가 사용 중인 자원을 점유하기 위해 대기한다.
(3) 비선점: 다른 프로세스에 할당된 자원을 뺏을 수 없다.
(4) 환형 대기: 프로세스가 자신의 자원을 점유하면서 앞이나 뒤에 있는 프로세스의 자원 요구
9. CPU 스케줄링
(1) 목적: 모든 프로세스를 공평하게 실행시키기 위한 방법
(2) 스케줄링 알고리즘의 종류
- FCFS(First Come First Serve): 비선점형, 선입선출
- SJF(Shortest Job First): 비선점형, 실행 시간이 짧은 것부터 실행
- RR(Round Robin): 선점형, 타임 슬라이스(또는 타임 퀀텀)동안만 프로세스 실행 후 교체
- SRTF(Shortest Remaining Time First): 선점형, 남은 프로세스 중 실행 시간이 가장 짧은 프로세스 실행
(3) 스케줄러의 종류
- 장기 스케줄러: 어떤 프로세스를 준비 큐에 넣을지 결정, 시스템에 들어오는 작업(job)을 선택하여 준비 상태 큐로 보냅니다.
- 단기 스케줄러: 준비 큐에 있는 프로세스 중 어떤 프로세스를 CPU에 할당할지 결정, 준비 상태 큐에 있는 프로세스 중에서 어느 프로세스를 다음으로 실행할지를 결정합니다.
- 중기 스케줄러: 메모리에 로드된 프로세스 수 관리, 프로세스를 일시적으로 중단(suspend)하거나 다시 활성화(resume)하는 역할을 한다, 프로세스의 스와핑(swapping)과 같은 메모리 관리를 담당합니다.
10. 비연속 메모리 할당
(1) 페이징
- 프로세스의 메모리 영역과 물리 메모리 영역을 일정 크기로 분할하는 방식
- 프로세스의 메모리 영역을 페이지로, 물리 메모리 영역을 프레임으로 나눔
- 내부 단편화 문제 발생 가능
(2) 세그먼테이션
- 프로세스를 논리적 단위로 분할하는 방식
- 데이터를 보호하기 쉬움
- 스택 세그먼트 영역에서 스택오버플로 발생 가능
11. 가상 메모리
(1) 메모리 공간의 한계를 극복하기 위해 고안한 방식으로 프로세스 일부만 메모리에 올린다.
(2) 많은 프로세스를 메모리에 로드할 수있다.
(3) 요구 페이징: 필요한 페이지만 메모리에 로드, 페이지 폴트 발생 가능
(4) 스레싱: 가상 메모리 환경에서 다중 프로그래밍 정도가 높아지면서 페이지 폴트가 빈번히 발생해 CPU 이용률이 오히려 낮아지는 증상
예상 면접 질문
질문1. 시스템 콜을 설명해 보세요
시스템 콜은 커널 모드와 사용자 모드 간에 필요한 정보를 주고받기 위해 호출하는 함수이다. OS는 사용자가 하드웨어의 주요 자원에 쉽게 접근할 수없게 커널 모드와 사용자 모드로 구분한다. 프로세스에서 자원에 접근해 작업을 처리해야 할 때는 시스템 콜로 필요한 요청을 하고 그에 대한 결과 값을 돌려받게 된다.
TIP) 시스템 콜의 역할 및 필요한 이유를 알아야 한다. OS는 커널 모드와 사용자 모드로 나뉘어 사용자가 자원에 쉽게 접근할 수 없으므로 자원에 접근하려면 시스템 콜을 호출해야 한다.
질문2. 프로세스의 메모리 구조를 설명하시오.
프로세스의 메모리 영역은 스택,힙,데이터,코드로 나눌 수 있다. 스택은 지역 변수와 함수의 매개변수가 저장되는 영역이고, 힙은 동적 메모리 할당이 일어나는 영역이다. 데이터 영역에는 전역 변수, 정적 변수, 배열, 구조체 등이 저장된다. 데이터 영역은 다시 BSS영역과 데이터 영역으로 나눌 수 있다. 코드 영역은 기계어가 저장되는 공간이다.
TIP) 각 메모리 영역에 어떠한 것들이 저장되는지 알고 있어야 한다. BSS 영역은 데이터 영역과 묶어서 설명하거나 생략해도 된다. 추가로, 스택 영역과 힙 영역의 특징과 목적을 이해하면 스택 오버플로와 힙 오버플로 등 메모리 영역 관련 개념을 이해할 때 도움된다.
질문3. 프로세스와 스레드의 차이점을 설명해 보세요.
프로세스는 실행 중인 하나의 프로그램을 의미하며 실행의 단위라고 할 수 있다. 반면에 스레드는 프로세스 내에서 실행되는 흐름의 단위를 의미한다. 프로세스는 독립적인 메모리 영역을 갖지만, 스레드는 스택 영역만 독립적이고, 그 외 영역은 다른 스레드와 공유한다.
TIP) 프로세스의 개념을 정확하게 파악하는 것이 중요하다. 프로세스는 실행 중인 하나의 프로그램이며 프로그램은 명령어 집합이라는 점을 유의해야 한다. 프로세스는 메모리 영역이 독립적이지만, 스레드는 스택 영역을 제외한 메모리 영역을 공유한다.
질문4. 스택 오버플로와 힙 오버플로에 관해 설명해 보세요.
스택 오버플로는 메모리에 스택 영역이 힙 영역을 침범할 때 발생한다. 그 예시로 과도한 재귀 호출이 있다. 힙 오버플로는 힙 영역이 스택 영역을 침범하는 경우이다. 예시로는 과도한 메모리 동적 할당이 있다.
TIP) 스택 오버플로와 힙 오버플로가 발생하는 예를 함께 답변하면 좋다. 스택 영역은 지역 변수와 함수의 매개변수가 저장되는 영역으로, 과도한 재귀 호출이 발생하면 힙 영역을 침범하게 되어 스택 오버플로가 발생한다. 그리고 힙은 동적 메모리 영역으로 과도하게 동적 할당하면 힙 오버플로가 발생한다.
질문5. PCB가 무엇인지 설명해 보시오.
PCB는 Process Control Block의 약자로, 프로세스에 대한 정보를 저장하는 구조체이다. 저장되는 정보로는 프로세스의 고유 아이디인 PID, 프로세스가 다음으로 실행해야 하는 명령어의 주소 값인 PC, CPU의 레지스터에 저장되는 정보 등이 있다.
TIP) PCB는 프로세스에서 빠질 수 없는 내용이다. 따라서 저장되는 정보를 모두 외울 필요는 없지만, 몇 가지는 설명할 수 있을 정도로 알고 있어야 한다.
질문6. 멀티 프로세스와 멀티 스레드의 차이점을 설명해 보시오.
멀티 프로세스는 응용 프로그램 하나를 프로세스 여려 개로 구성하는 것이다. 반면에 멀티 스레드는 한 프로세스 안에서 여러 스레드로 작업을 처리하는 것이다. 프로세스는 독립적인 메모리 영역을 갖기 때문에 자원 공융와 통신을 하려면 IPC를 활용해야 한다. 스레드는 자원 공간을 공유하므로 스레드 간 통신과 자원 공유가 간단하고 프로세스 대비 콘텍스트 스위칭 비용이 적게 들지만, 동기화가 필요하다.
TIP) 멀티 프로세스와 멀티 스레드의 중요한 차이점 중 하나는 자원 공간의 공유 여부다. 자원 공간을 공유할 수 없는 프로세스 간 자원 공유 방법인 IPC에 대해 연결 질문이 나올 수 있다. 추가로 답변에 스레드 구현 경험과 데이터 동기화 문제 해결 경험을 녹아내면 면접 흐름을 이끌고 개발 경험을 강조할 수 있다.
https://www.youtube.com/watch?v=ktWcieiNzKs&t=1174s
https://cookie-dev.tistory.com/29
동시성 이슈 해결 1탄 - 코드 레벨 동시성 이슈 (Synchronized, Atomic)
재고 처리 기능을 개발하는 과정에서 동시성 이슈가 발생하여 원인과 해결 방법에 대해 정리해 봤습니다. 내용은 "요구사항 구현" - "동시성 이슈 재현" - "원인 분석" - "해결 방법" 순서로 구성했
cookie-dev.tistory.com
질문7. 동시성과 병렬성을 설명해 보세요.
동시성은 하나의 코어에서 작업을 번갈아 가면서 실행해 여러 작업을 처리하는 것을 의미한다. 이 방식은 CPU에서 처리 중인 작업을 변경하기 위해 콘텍스트 스위칭이 일어나 오버헤드가 발생한다. 반면에 병렬성은 여러 코어에서 처리하는 것을 의미한다. 물리적인 시간 관점에서 여러 작업이 동시에 처리되는 방식이다.
Tip) 동시성의 핵심은 하나의 코어에서 여러 작업을 번갈아 처리하지만, 사용자 입장에서는 동시에 처리되는 것처럼 보인다는 점이다. 병렬성은 멀티 코어를 이용해 물리적인 시간 관점에서 동시에 여러 작업을 실행한다는 것이 핵심이다.
질문8. 콘텍스트 스위칭이 무엇인지 설명해 보세요.
콘텍스트 스위칭은 CPU가 처리 중인 프로세스를 변경하는 것을 의미한다. CPU는 하나의 로세스만 처리할 수 있어서 멀티 프로세스 환경에서는 콘텍스트 스위칭이 발생한다. CPU 스케줄러에 의해 인터럽트가 발생하면 실행 상태의 프로세스가 준비 또는 대기 상태로 전환되고, 다음에 실행할 프로세스가 실행 상태로 전환된다. 이때 레지스터에 저장된 프로세스 정보가 바뀌면서 오버헤드가 발생하게 된다.
Tip) 멀티 프로세서의 단점인 오버헤드를 소개하고 이를 멀티 스레드로 보완할 수 있다고 설명하면 멀티 스레드에 관해 알고 있다는 것을 보여줄 수 있다.
질문9. 멀티 프로세서에서 콘텍스트 스위칭과 멀티 스레드에서 콘텍스트 스위칭의 차이점을 설명해 보세요.
가장 큰 차이점은 멀티 스레드에서 콘텍스트 스위칭할 때 멀티 프로세스보다 오버헤드가 적게 발생한다는 점이다. 멀티 프로세스는 프로세스 별로 고유한 메모리 영역을 갖는 반면, 멀티 스레드는 스택 영역을 제외한 메모리 영역을 공유한다. 그래서 레지스터에 로드해야 하는 데이터 양이 적어서 오버헤드가 적게 발생한다.
Tip) 이 질문으로 콘텍스트 스위칭에 대한 이해도뿐만 아니라 멀티 프로세스와 멀티 스레드의 이해도까지 확인할 수 있다. 따라서 콘텍스트 스위칭에서 발생하는 오버헤드와 프로세스와 스레드가 갖는 메모리 영역의 차이를 설명하는 내용에 답변이 들어가면 좋다.
질문10. 프로세스 동기화에 대해 설명해 보세요.
프로세스 동기화는 여러 프로세스 또는 스레드가 하나의 공유 자원에 접근해도 일관성을 유지하는 것을 의미한다. 공유 자원에 접근하는 코드를 임계 영역이라고 하며, 임계 영역에 대한 상호배제 기법이 잘 이뤄져야 프로세스 동기화를 할 수 있다. 상호배제 기법으로는 뮤텍스와 세마포어가 있다.
Tip) 프로세스 동기화에 대한 답변할 때 중요한 임계 영역, 뮤텍스, 세마포어를 짚고 넘어가는 것이 좋다. 추가로 임계 영역 문제를 해결하기 위한 조건으로 상호배제 기법뿐만 아니라 진행과 한정도니 대기에 대해서도 알고 있으면 좋다.
질문11. 뮤텍스와 세마포어의 차이점을 설명해 보세요.
뮤텍스와 세마포어는 프로세스 동기화를 위한 상호배제 기법이다. 이 중 뮤텍스는 락을 가진 하나의 프로세스만 임계 영역에 접근할 수 있게 하는 동기화 방식이다. 이 방식을 사용하면 임계 영역에 접근하려는 프로세스는 반복문을 돌며 임계 영역에 접근 가능한지 확인하게 되는데, 이러한 현상을 스핀락이라고 한다. 반면에 세마포어는 임계 영역에 특정 개수의 프로세스가 접근할 수 있게 제어하는 방식이다. 임계 영역에 접근이 불가능하면 해당 프로세스는 대기 상태로 들어가고, 이후 임계 영역을 처리 중이던 프로세스가 임계 영역을 나가면서 대기 상태인 프로세스를 깨우게 된다.
Tip) 뮤텍스와 세머포어의 목적이 동기화라라는 것을 이해해야 한다. 또한, 뮤텍스와 세마포어의 특징을 알아 두기를 추천한다.
질문12. 스레드 안전의 의미가 무엇이며 이를 구현하는 방법은 무엇인가요?
스레드 안전은 하나의 자원 또는 객체에 여러 스레드가 접근해도 프로그램을 실행하는 데 문제가 없는 것을 의미합니다.
자바에서 스레드 안전을 구현할 때 Synchronized 키워드를 사용하는 방법이 있다. Synchronized 키워드는 임계 영역에 하나의 스레드만 접근할 수 있게 해서 이 키워드를 사용한 블록 단위로 락의 획득 및 해제가 발생한다. Synchronized 키워드를 사용할 때 블록을 크게 잡으면 성능 저하 문제가 생길 수 있으므로 임계 영역을 최소화해야 한다.
질문13. 비선점형 스케줄링 알고리즘과 선점형 스케줄링 알고리즘을 설명해 보세요.
비선점형 스케줄링은 하나의 프로세스가 실행 중이면 해당 프로세스가 종료될 때까지 다른 프로세스가 실행될 수 없다.FCFS 스케줄링과 SJF 스케줄링이 대표적인 예이다. 선점형 스케줄링은 하나의 프로세스가 실행 중일 때 스케줄러가 실행 중인 프로세스를 중단시키고 다른 프로세스를 실행할 수 있다. 대표적인 예로 RR 스케줄링과 SRTF 스케줄링이 있다.
Tip) 비선점형 스케줄링과 선점형 스케줄링의 특징과 대표적인 알고리증을 알고 있어야 한다. 특히 FCFS 스케줄링, SJF 스케줄링, RR 스케줄링, SRTF 스케줄링은 이름이 어떠한 단어들의 약자인지 알아야 하고, 작동 방식도 이해해야 한다. 그래야 프로세스 실행 순서 또는 프로세스의 평균 대기 시간을 계산하는 질문이 나와도 답할 수 있다.
질문14. OS의 메모리 관리 전략 중 페이징과 세그먼테이션을 비교해서 설명해 보세요.
페이징과 세그먼테이션은 비연속 메모리 할당 방식으로, 프로세스가 메모리에 연속적으로 할당될 때 발생할 수 있는 문제를 보완하는 기법이다. 페이징은 논리 메모리 영역과 물리 메모리 영역을 같은 크기로 나누고 각각의 영역을 페이지와 프레임이라고 일컫는다. 이 기법은 메모리 할당 문제를 해결할 수 있지만, 내부 단편화가 발생할 수 있다. 반면에 세그먼테이션은 프로세스를 논리적 단위로 분할한다. 프로세스의 메모리 영역을 분할했기 때문에 메모리 보호가 쉽지만, 외부 단편화 문제가 발생할 수 있다.
Tip) OS의 메모리 관리 전략 중 비연속 메모리 할당인 페이징과 세그먼테이션의 차이점을 알고 있어야 한다. 또한, 각각 내부 단편화와 외부 단편화라는 단점이 있다는 것도 알고 있으면 좋다.
질문15. 가상 메모리가 무엇인지와 가상 메모리가 필요한 이유를 설명해 보세요.
가상 메모리는 프로세스 전체가 아닌 일부만 메모리 영역으로 옮기고 나머지는 보조 기억장치인 디스크에 옮겨 실제 메모리 영역보다 큰 영역을 사용하는 것처럼 보이게 하는 방식이다. 가상 메모리는 한정된 메모리의 영향을 덜 받고 많은 프로세스를 실행하기 위해 필요합니다.
Tip) 가상 메모리에 관한 질문이 나왔을 때 구현 방법인 요구 페이징에 대한 이야기를 덧붙임으로써 연결 질문을 이어서 받을 수 있다.
질문16. 스레싱이 무엇인가요?
스레싱이란 가상 메모리 환경에서 다중 프로그래밍 정도가 높아지면서 페이지 폴트가 빈번히 발생해 CPU 이용률이 오히려 낮아지는 증상을 의미한다. 즉, 실제 시스템이 작동되는 시간보다 페이지 교체가 빈번히 일어나 발생하는 문제이다. 이러한 문제를 예방하기 위해 워킹 세트를 설정할 수 있다. 워킹 세트는 지역성을 기반으로 자주 사용하는 페이지를 저장해 두는 것을 의미한다.
Tip) 스레싱은 가상 메모리와 관련해 출제 빈도가 높은 개념이다. 스레싱의 개념과 해결 방안은 무엇인지 알고 있어야 한다.
질문17. 캐시 메모리에 대해 설명해 보세요.
캐시 메모리는 CPU와 메모리 간 속도 차이를 좁히려고 사용하는데, CPU에서 자주 사용하는 데이터를 접근 속도가 빠른 캐시 메모리에 저장한다. 이때 적중률을 높이기 위해 자주 사용하는 데이터를 저장하는 지역성 원리를 사용한다.
Tip) 캐시 메모리의 핵심은 CPU와 메모리 간 데이터 접근 시 속도 차이를 줄이기 위해 사용한다는 점이다. 이를 파악한 상태에서 어떠한 원리를 적용하는지 이해하고 답변해야 한다.
'Backend > CS' 카테고리의 다른 글
[Tech Interview] Data Structure (0) | 2024.05.17 |
---|---|
[Tech Interview] Network (0) | 2024.05.08 |
[면접을 위한 CS 전공지식 노트] 운영체제 (2) | 2024.03.29 |
TCP, UDP (1) | 2024.01.04 |
IP(인터넷 프로토콜) (0) | 2024.01.04 |