# Table of Contents
# 프로세스
- 메모리에 로드되어 연속적으로 실행되고 있는 프로그램
- 네 가지 영역으로 구분된다.
Code
: 컴파일된 코드가 저장되는 영역Data
: 전역변수, Static 변수가 저장되는 영역Stack
: 지역변수, 매개변수가 저장되는 영역Heap
: 동적 할당 영역
# PCB
- Process Control Block
- 멀티 프로세스 환경에서 각 프로세스를 구분하기 위해 운영체제가 유지하고 있는 프로세스 정보
- 운영체제가
Context Switching
을 할 때 필요로 한다. - PID, 상태, 스케줄링 우선순위 등의 정보를 저장한다.
# 스레드
- 프로세스의
실행 흐름
- 하나의 프로세스는 여러
실행 흐름
을 가질 수 있으며, 이를멀티 스레드
라고 한다. - 모든 스레드는
Code
,Data
,Heap
영역을 공유하지만 각각의Stack
을 사용한다.
# 인터럽트
- 한 프로세스가 실행 중일 때 다른 프로세스를 실행하기 위하여 현재 프로세스를 중지하거나, 입출력에 의해 현재 프로세스를 중단시키는 것
- 인터럽트의 처리과정
- 인터럽트가 발생하면 운영체제가 현재의 프로세스 상태를 저장하고 인터럽트를 처리한다.
- 이전 프로세스로 복구한다.
# Context Switching
- 현재 프로세스 (또는 스레드)의 상태를 저장하고 다른 프로세스 (또는 스레드)로 제어권을 넘기는 작업
# 멀티 프로세스 대신 멀티 스레드
- 멀티 프로세스의
Context Swtiching
비용이 더 크다. - 멀티 스레드는
Stack
영역만 스위칭하면 되지만 멀티 프로세스는Code
,Data
,Heap
영역까지 스위칭해야하기 때문이다.
# 공유 자원과 임계 영역
- 멀티 프로세스 (또는 멀티 스레드) 환경에서는 여러 프로세스가 하나의 자원에 접근할 수 있다. 이를
공유 자원
이라고 한다. - 공유 자원에 접근하는 코드를
임계 영역(Critical Section)
이라고 한다. - 공유 자원은 한 순간에 하나의 프로세스만 접근할 수 있도록 해야하는데
동기화
해야 한다.
# 동기화
- 멀티 스레드 환경에서 한 순간에는 하나의 스레드만 공유자원에 접근할 수 있도록 하는 것.
- 동기화에는 다음과 같은 방법이 있다.
# Mutex, Semaphore
둘 다 한 순간에 여러 프로세스, 스레드가 동시에 공유자원에 접근하지 못하도록 하는 기법이다.
Mutex
:- Locking 메커니즘
- Mutex는 0 또는 1 값만 올 수 있는 정수형 변수다.
- 프로세스가 Mutex를 확인한 후 0이면 Mutex를 1로 설정한 후 공유 자원에 접근한다. 프로세스가 Mutex를 확인한 후 1이면 Mutex가 0이 될 때까지 확인하면서 기다린다.
- 결국 Mutex는 한 순간에 하나의 프로세스, 스레드만 공유자원에 접근하도록 한다.
- 이진 세마포어라고도 한다.
Semaphore
- Signaling 메커니즘, 즉 wait()과 signal() 메소드를 사용한다.
- Semaphore는 내부에 정수형 변수 N을 유지하고 있는 객체다.
- 프로세스가 변수가 N보다 작은지 확인한 후 N보다 작으면 N+1로 설정 후 공유자원에 접근한다. 프로세스가 변수 N을 확인한 후 N이면 N보다 작아질 때까지 기다린다. 공유자원을 사용 중인 프로세스는 자원을 다 사용하면 기다리고 있는 프로세스들에게 신호를 보낸다.
- 결국 Semaphore는 정해진 수 만큼의 프로세스만 공유자원에 접근하도록 한다.
# 데드락
- 프로세스들이 서로의 자원을 점유한 상태에서 상대방의 자원을 무한정 기다리는 상태
# 블로킹과 논블로킹
대부분의 어플리케이션 런타임은 동기/블로킹 모델
또는 비동기/논블로킹 모델
을 따른다. 스프링 MVC는 동기/블로킹 모델이고 Node.js나 WebFlux는 비동기/논블로킹 모델이다.
# 블로킹
함수 A
에서 함수 B
를 호출한다고 가정하자. 함수 A
실행 도중에 함수 B
를 호출했을 때 함수 B
가 끝날 때까지 기다렸다가 남은 부분을 실행하는 것을 블로킹
이라고 한다.
# 논블로킹
함수 A
실행 도중에 함수 B
를 호출했을 때 함수 B
가 끝날 때까지 기다리지 않고 자신의 실행흐름을 수행하는 것을 논블로킹
이라고 한다.
# 동기와 비동기
# 동기
함수 A
에서 함수 B
를 호출한다고 가정하자. 함수 A
실행 도중에 함수 B
를 호출했을 때 함수 B
가 끝날 때까지 기다렸다가 남은 부분을 실행하면 두 함수 사이에 연관 관계가 있기 때문에 동기화
되었다고 한다.
# 비동기
함수 A
실행 도중에 함수 B
를 호출했을 때 함수 B
가 끝날 때까지 기다리지 않고 자신의 실행흐름을 수행하기 때문에 연관 관계가 없으며, 이를 비동기
라고 한다.
결국 블로킹/논블로킹
, 동기/비동기
는 관점의 차이이며, 일반적인 시스템은 동기/블로킹 모델
과 비동기/논블로킹
모델로 구분된다. 비동기/논블로킹
모델에서는 일반적으로 호출하는 함수의 종료 시점을 알 수 없기 때문에 종료 시점에 실행할 코드를 콜백, 람다 형태로 전달한다. 다만 콜백이 너무 길어저 코드가 지저분해질 수도 있기에 Kotlin
에서는 코루틴의 suspend
함수, JavaScript
는 async/await
키워드를 사용할 수 있다.
# CPU 스케줄링
- 멀티 프로세스 환경에서는 대부분 CPU 코어 수 보다 많은 프로세스가 실행되기 때문에 이 프로세스를
병행(Concurrency)
적으로 돌아가면서 실행시켜야한다. 이 전략을CPU 스케쥴링
이라고 한다. 비선점형
: 하나의 프로세스가 끝나기 전까지 다른 프로세스가 선점하지 못한다.- FIFO
- SJF(Shortest Job First)
- 실행 시간 추정치가 가장 작은 작업을 먼저 수행
- 실행 시간이 긴 작업은 무기한 연장되기 때문에 에이징 기법을 사용
선점형
: 하나의 프로세스가 끝나지 않아도 다른 프로세스가 선점할 수 있다.- Round Robin
- 일정한 시간 만큼 돌아가면서 실행
- SRT (Shortest Remaining Time)
- 남아있는 실행 시간의 추정치가 가장 작은 프로세스를 먼저 수행
- 현실적으로 남아있는 실행 시간 계산이 어렵다.
- Round Robin
# 기아 상태(Starvation)
- 우선순위가 낮은 프로세스가 실행되지 않는 상태.
Aging
으로 해결할 수 있다.
# 지역성
프로그램이 실행될 때 모든 영역을 골고루 참조하는게 아니라 특정 시간, 특정 공간에 집중적으로 참조한다는 특성
시간 지역성
: 최근 참조한 영역이 미래에도 계속 참조할 가능성이 높다.공간 지역성
: 최근 참조한 지역의 근처를 계속 참조할 가능성이 높다.Cache Memory
가 지역성을 응용한 대표적인 기술
# 가상 메모리
- 주기억장치는 가격도 비싸고 크기의 한계가 있다. 이러한 한계를 극복하고 주기억장치보다 더 큰 프로그램을 실행하기 위해 보조 기억장치의 영역 일부를 주기억장치처럼 사용하는 것
- 프로그램을 페이지라는 단위로 분할하고, 현재 실행중인 페이지만 주기억장치에 로드하여 실행한다.
# 쉘, 커널
쉘(Shell)
:- 사용자의 명령어를 해석하여 커널에 전달한다.
bash
,zsh
같이 다양한 쉘이 존재한다.
커널(Kernel)
:- 운영체제의 핵심
- CPU, 메모리, 프로세스, 입출력, 네트워크, 보안 등의 자원을 스케줄링하고 관리한다.