diff --git a/application_form (DDL) [ject-readonly].md b/application_form (DDL) [ject-readonly].md
new file mode 100644
index 0000000..b839ba8
--- /dev/null
+++ b/application_form (DDL) [ject-readonly].md
@@ -0,0 +1,148 @@
+classDiagram
+direction BT
+class application_form {
+ datetime(6) created_at
+ bigint member_id
+ bigint recruit_id
+ datetime(6) updated_at
+ mediumtext content
+ bigint id
+}
+class email_send_group {
+ varchar(30) code
+ varchar(100) description
+ varchar(100) template_name
+ datetime(6) created_at
+ datetime(6) updated_at
+ bigint id
+}
+class jectalk {
+ datetime(6) created_at
+ datetime(6) updated_at
+ varchar(50) name
+ varchar(2083) image_url
+ varchar(2083) youtube_url
+ varchar(255) summary
+ bigint id
+}
+class member {
+ datetime(6) created_at
+ datetime(6) updated_at
+ varchar(12) phone_number
+ varchar(20) name
+ varchar(30) email
+ varchar(255) pin
+ varchar(45) job_family
+ varchar(10) role
+ bigint semester_id
+ bigint id
+}
+class mini_study {
+ datetime(6) created_at
+ datetime(6) updated_at
+ varchar(50) name
+ varchar(2083) image_url
+ varchar(2083) link_url
+ varchar(255) summary
+ bigint id
+}
+class portfolio {
+ bigint application_form_id
+ datetime(6) created_at
+ bigint file_size
+ datetime(6) updated_at
+ varchar(2083) file_url
+ varchar(255) file_name
+ int sequence
+ bigint id
+}
+class project {
+ date end_date
+ date start_date
+ datetime(6) created_at
+ bigint team_id
+ datetime(6) updated_at
+ varchar(100) name
+ varchar(100) summary
+ varchar(2083) service_url
+ varchar(2083) thumbnail_url
+ text description
+ varchar(255) tech_stack
+ varchar(30) category
+ bigint semester_id
+ bigint id
+}
+class project_intro {
+ int sequence
+ datetime(6) created_at
+ bigint project_id
+ datetime(6) updated_at
+ varchar(2083) image_url
+ varchar(30) category
+ bigint id
+}
+class question {
+ datetime(6) created_at
+ bigint recruit_id
+ datetime(6) updated_at
+ varchar(100) title
+ varchar(255) label
+ varchar(255) input_hint
+ varchar(10) input_type
+ tinyint(1) is_required
+ int max_text_length
+ int sequence
+ int max_file_size
+ varchar(255) select_options
+ bigint id
+}
+class recruit {
+ datetime(6) end_date
+ datetime(6) start_date
+ datetime(6) created_at
+ datetime(6) updated_at
+ varchar(45) job_family
+ bigint semester_id
+ bigint id
+}
+class review {
+ datetime(6) created_at
+ datetime(6) updated_at
+ varchar(2083) link_url
+ varchar(255) description
+ varchar(255) summary
+ varchar(255) title
+ bigint id
+}
+class semester {
+ varchar(20) semester_name
+ tinyint(1) is_recruiting
+ datetime(6) created_at
+ datetime(6) updated_at
+ bigint id
+}
+class team {
+ datetime(6) created_at
+ datetime(6) updated_at
+ varchar(30) name
+ bigint id
+}
+class team_member {
+ datetime(6) created_at
+ bigint member_id
+ bigint team_id
+ datetime(6) updated_at
+ bigint id
+}
+
+application_form --> member : member_id:id
+application_form --> recruit : recruit_id:id
+member --> semester : semester_id:id
+portfolio --> application_form : application_form_id:id
+project --> semester : semester_id:id
+project --> team : team_id:id
+project_intro --> project : project_id:id
+question --> recruit : recruit_id:id
+recruit --> semester : semester_id:id
+team_member --> member : member_id:id
+team_member --> team : team_id:id
diff --git a/contents/posts/os/1/img.png b/contents/posts/os/1/img.png
new file mode 100644
index 0000000..390a74c
Binary files /dev/null and b/contents/posts/os/1/img.png differ
diff --git a/contents/posts/os/1/img_1.png b/contents/posts/os/1/img_1.png
new file mode 100644
index 0000000..12838a9
Binary files /dev/null and b/contents/posts/os/1/img_1.png differ
diff --git a/contents/posts/os/1/img_3.png b/contents/posts/os/1/img_3.png
new file mode 100644
index 0000000..f89bf16
Binary files /dev/null and b/contents/posts/os/1/img_3.png differ
diff --git a/contents/posts/os/1/img_4.png b/contents/posts/os/1/img_4.png
new file mode 100644
index 0000000..6e0c097
Binary files /dev/null and b/contents/posts/os/1/img_4.png differ
diff --git a/contents/posts/os/1/index.md b/contents/posts/os/1/index.md
new file mode 100644
index 0000000..cd70f96
--- /dev/null
+++ b/contents/posts/os/1/index.md
@@ -0,0 +1,93 @@
+---
+title: "1. 운영체제의 개념과 구조"
+description:
+date: 2025-09-03
+update: 2025-09-03
+tags:
+ - 운영체제
+series: "운영체제"
+---
+
+## 운영체제(OS, Operating System)
+
+[운영체제는 컴퓨터라는 기계 안에서 프로그램과 하드웨어 사이에서 문제없이 그리고 효율적으로 잘 돌아가도록 관리해주는 소프트웨어이다.](https://en.wikipedia.org/wiki/Operating_system#:~:text=An%20operating%20system%20(OS)%20is%20system%20software%20that%20manages%20computer%20hardware%20and%20software%20resources%2C%20and%20provides%20common%20services%20for%20computer%20programs.)
+
+
+
+운영체제가 없으면 어떻게 될까? 꼭 필요할까?
+
+> _A computer is a machine that can be programmed to automatically carry out sequences of arithmetic or logical operations_
+> (컴퓨터는 산술적 또는 논리적 연산(계산)의 순서를 자동으로 수행하도록 프로그래밍할 수 있는 기계이다).
+> [ - wikepedia](https://en.wikipedia.org/wiki/Computer#:~:text=A%20computer%20is%20a%20machine%20that%20can%20be%20programmed%20to%20automatically%20carry%20out%20sequences%20of%20arithmetic%20or%20logical%20operations%20(computation).)
+
+운영체제가 없다면 컴퓨터는 그저 하드웨어의 집합체에 불과하다.
+사용자는 프로그램을 실행하기 위해서 매번 하드웨어를 직접 제어해야 하며, 이렇게 하는 것은 매우 비효율적일거다.
+또한 직접 제어를 한다고 해도 하드웨어의 성능은 제한적이므로 이 환경에서 최대한의 성능을 끌어내기 위해 최적화라는 고통스러운 작업을 해야 할 것이다.
+이러한 상황을 상상해보면 "배보다 배꼽이 더 크다"라는 말이 떠오른다.
+
+실제로 운영체제라는 개념이 있기 전에는 사용자들이 하나의 작업을 위해 펀치카드를 소지하며 관리해야 했다.
+그리고 단순 하드웨어에 올려 실행하는 과정의 방식이기에 한 번에 하나의 프로그램만 실행할 수 있었고, 해당 프로그램이 끝나야 다른 프로그램을 수행할 수 있었다.
+지금처럼 복잡한 방식의 프로그램은 꿈도 꿀 수 없었을 것이다.
+
+이러한 문제를 해결하기 위해 운영체제가 나왔고, 다음과 같은 목적을 지닌다.
+
+- 사용자에게 컴퓨터의 프로그램을 쉽고 효율적으로 실행할 수 있는 환경을 제공한다.
+- 컴퓨터 시스템 하드웨어 및 소프트웨어 자원을 여러 사용자 간에 효율적 할당, 관리, 보호하는 것
+- 운영체제는 제어 프로그램으로서 사용자 프로그램의 오류나 잘못된 자원 사용을 감시하는 것과 입출력 장치 등의 자원에 대한 연산과 제어를 관리한다.
+
+운영체제은 위와 같은 목적을 위해 다양한 방식을 가지고 있다.
+
+### 일괄 처리 시스템 (Batch Operating System)
+
+사용자의 개입없이 비슷한 작업들을 모아서 순차적으로 처리하는 방식이다.
+한 작업이 끝나야 다음 작업이 실행되기 때문에 모든 작업이 완료될 때까지 기다릴 수 있는 환경에서 사용된다.
+주로 대용량 데이터를 처리하거나 시간이 많이 소요되는 작업에 활용되며, 사용자의 개입이 필요하지 않고 반복적인 작업을 일괄적으로 처리할 수 있다.
+
+### 다중 프로그래밍 시스템 (Multi Programming System)
+
+이 방식은 CPU을 최대한 사용하고 하는 방식으로,
+여러 응용프로그램을 메모리에 동시에 올라가 CPU가 쉬지 않고 여러 작업을 번갈아서 실행하며 항상 연산을 수행하는 상태로 활용하는 방식이다.
+하나의 프로그램을 실행하는 동안 다른 프로그램은 대기하거나 I/O 작업 등을 수행하며 메모리에 올라간 상태로 대기하게 된다.
+운영 체제는 이런 과정에서 CPU를 배분하는 작업 스케줄링과 CPU 스케줄링을 진행하며,
+이를 통해 시스템 자원을 효율적으로 활용하고 응용 프로그램들이 서로 영향을 주지 않으면서 병렬적으로 실행된다.
+
+### 시분할 시스템 (Time Sharing System)
+
+이 방식은 CPU에 대해 일정 시간을 할당 받아 짧은 간격으로 번갈아 실행하는 방식이다.
+다중 프로그래밍 시스템에서는 Context Switching(CPU 점유 권한 전환)이 I/O작업에서만 발생한다.
+이를 통해서만 스케줄링을 할 경우 하나의 프로세스가 아주 오래 CPU를 독점하고 있는 상태가 발생할 수 있다는 문제점이 있다.
+이를 해결하기 위한 것이 시분할 시스템으로, 다중 프로그래밍과 비슷하지만 모든 프로세스가 특정 시간만 CPU를 점유하고 다른 프로세스에 권한을 넘겨주는 방식으로
+Context Switching 기준 시간으로 시분할을 구현해서 RR(Round-Robin) 알고리즘으로 스케줄링을 한다.
+
+### 대화형 시스템(Interactive System)
+
+앞서 설명한 일괄 처리 시스템은 처리해야할 작업들을 한번에 정의하고 일괄적으로 처리하는 방식이었다.
+이러한 일괄 처리 시스템의 문제점은 처리가 이루어지는 중에 시스템의 상태를 확인하기가 힘들고,
+작업이 끝나 결과가 도출되기 전까지는 작업을 수정할 수도 없다는 문제점이 있었다.
+이를 보완하기위해 등장한 시스템이 대화형 시스템으로,
+작업 중에도 사용자가 데이터, 명령 또는 작업을 입력하면 컴퓨터가 즉각적으로 해당 입력에 응답하는 사용자와 컴퓨터 간의 상호작용을 통해 작동하는 방식이다.
+
+## 커널(Kernel)
+
+그럼 우리들의 컴퓨터 속 운영체제는 어떻게 이러한 기능을 수행하고 있을까?
+
+[운영체제의 이러한 핵심적인 부분을 담당하고 수행하는 것이 바로 커널이다.](https://en.wikipedia.org/wiki/Kernel_(operating_system)#:~:text=A%20kernel%20is%20a%20computer%20program%20at%20the%20core%20of%20a%20computer%27s%20operating%20system%20that%20always%20has%20complete%20control%20over%20everything%20in%20the%20system.)
+
+
+커널을 한글로 번역하면 핵심이다! 재밌지 아니한가? 아무튼 다시 돌아와서 커널은 어떻게 운영체제의 기능을 수행할까?
+
+[커널은 하드웨어를 인터페이스로 제공하여 여러 사용자 또는 여러 프로세스가 하드웨어 즉 리소스를 효율적으로 관리하며 작업을 수행할 수 있도록 해준다.](https://en.wikipedia.org/wiki/Kernel_(operating_system)#:~:text=The%20kernel%27s%20interface%20is%20a%20low%2Dlevel%20abstraction%20layer.%20When%20a%20process%20requests%20a%20service%20from%20the%20kernel%2C%20it%20must%20invoke%20a%20system%20call%2C%20usually%20through%20a%20wrapper%20function.)
+여기서 중요한 점은 커널은 사용자가 직접 제어할 수는 없다.
+그 이유는 보안상 유저 어플리케이션이 함부로 운영체제의 리소스를 건들지 못하게 하기 위해서다.
+그래서 커널에는 하드웨어에 접근이 허가된 커널모드와 그렇지 못한 유저모드로 분리가 되어있다.
+
+
+
+커널의 구조는 위 사진과 같은데, 간단한 흐름을 설명하자면 사용자가 유저모드인 어플리케이션을 실행하면서 발생하는 요청이 시스템 콜을 통해 커널 모드로 전환이 된다.
+애플리케이션은 커널모드로 전환되었다가 작업을 끝낸 후 응답을 반환하면서 다시 유저모드로 되돌아 가게 된다.
+여기서 시스템 콜은 뭐지 싶을텐데 [어플리케이션의 요청이 커널에 접근해 시스템에 요청하는 것](https://en.wikipedia.org/wiki/System_call#:~:text=In%20computing%2C%20a%20system%20call%20(syscall)%20is%20the%20programmatic%20way%20in%20which%20a%20computer%20program%20requests%20a%20service%20from%20the%20operating%20system%5Ba%5D%20on%20which%20it%20is%20executed.)으로 간단히 유저모드에서 커널모드로 전환하는 것이라고 생각하면 된다.
+
+
+
+이러한 방식을 통해 사용자의 프로세스가 직접적으로 운영체제의 리소스를 함부로 변경하지 못하게 보호해준다.
+
diff --git a/contents/posts/os/2/img.png b/contents/posts/os/2/img.png
new file mode 100644
index 0000000..8dfbbbb
Binary files /dev/null and b/contents/posts/os/2/img.png differ
diff --git a/contents/posts/os/2/img_1.png b/contents/posts/os/2/img_1.png
new file mode 100644
index 0000000..ac1f74c
Binary files /dev/null and b/contents/posts/os/2/img_1.png differ
diff --git a/contents/posts/os/2/img_2.png b/contents/posts/os/2/img_2.png
new file mode 100644
index 0000000..33e4d72
Binary files /dev/null and b/contents/posts/os/2/img_2.png differ
diff --git a/contents/posts/os/2/img_3.png b/contents/posts/os/2/img_3.png
new file mode 100644
index 0000000..934762f
Binary files /dev/null and b/contents/posts/os/2/img_3.png differ
diff --git a/contents/posts/os/2/img_4.png b/contents/posts/os/2/img_4.png
new file mode 100644
index 0000000..f66afd8
Binary files /dev/null and b/contents/posts/os/2/img_4.png differ
diff --git a/contents/posts/os/2/index.md b/contents/posts/os/2/index.md
new file mode 100644
index 0000000..fb5e4c0
--- /dev/null
+++ b/contents/posts/os/2/index.md
@@ -0,0 +1,75 @@
+---
+title: "2. 커널의 작동 방식"
+description:
+date: 2025-09-04
+update: 2025-09-04
+tags:
+ - 운영체제
+series: "운영체제"
+---
+
+앞서, 운영체제란 무엇인지 그리고 커널에 대해 간단하게 알아봤다.
+이제 커널이 어떻게 작동하는지 제대로 알아보자.
+
+먼저 인터럽트(Interrupt)에 대해 알아야 한다.
+
+
+
+컴퓨터는 위 사진처럼 주변 입출력 기기와 서로 통신하는데
+이 과정에서 서로 입출력 요청이 오가는데 이때 입출력 메커니즘들이 발생된다.
+이중 하나가 인터럽트이다.
+
+
+인터럽트는 중단시키다라는 의미로 초인종과 같다고 할 수 있다.
+즉, 인터럽트가 발생하면 잠깐 멈추고 다시 실행된다.
+
+
+
+실제 발생하는 대부분의 인터럽트는 I/O 인터럽트이다.
+예를들면, 우리가 자바에서 print을 할 때 print라는 API를 파일이라는 인터페이스를 통해서 유저모드에서 커널 모드로 시스템 콜이 발생한다.
+유저모드 API에서 커널모드 구성요소에서 시스템 콜이 이어지고 디바이스 드라이버를 제어하기 시작하는데
+[이때 디바이스 드라이버가 인터럽트를 CPU에 요청한다. 이 행위를 IRQ라고 한다.](https://en.wikipedia.org/wiki/Interrupt_request#:~:text=In%20a%20computer,or%20mouse%20movements.)
+이러한 IRQ는 장치마다 다른 번호로 관리하게 된다.
+아무튼 출력기기에 출력이 되면, 다시 역순으로 디바이스(하드웨어)에서 디바이스 드라이버로,
+디바이스 드라이버에서 커널 모드로 해서 최종적으로 유저 모드로 다시 돌아오게 된다.
+
+
+이때, 이러한 행위 도중 wait을 걸면 블라킹(동기) 안걸면 논블라킹(비동기)으로 동작하게 된다.
+
+인터럽트에는 우선순위가 있고 외부 인터럽트인지 내부 인터럽트인지에 따라 우선순위가 달라진다.
+
+먼저, 외부 인터럽트로 내부 인터럽트보다 우선 시 된다.
+
+그 중에서도 우선 순위가 있는데, 다음과 같다.
+- 전원 이상 인터럽트: 말 그대로 정전 또는 파워 이상
+- 기계 착오 인터럽트: CPU의 기능적인 오류.
+- 외부 신호 인터럽트: 타이머 또는, 키보드 인터럽트 키(Ctrl + Alt + Delete). 외부장치로부터 인터럽트 요청이 있는 경우. I/O 인터럽트와 다른 개념이다.
+- 입출력 인터럽트: 입출력 장치가 데이터 전송을 요구하거나 전송이 끝나 다음 동작이 수행되어야 할 경우. 입출력 데이터에 이상이 있는 경우. 우리가 자주 다루게 될 인터럽트 부분이다.
+
+이제 내부 인터럽트인데, 사실 우리가 주로 다루게 될 것은 외부 인터럽트에 있어 내부 인터럽트는 뭐가 있는지만 대강 본다.
+
+- 명령어 잘못 인터럽트: 잘못된 명령어나 잘못된 데이터를 사용할 때 발생하며 Trap이라 부른다,
+- 프로그램 검사
+- 소프트웨어 인터럽트(=SVC, SuperVisor Call)
+
+인터럽트 동작 순서에 대해 다시 살펴보면 다음과 같은데,
+
+1. 인터럽트 요청
+2. 프로그램 실행 중단
+3. 현재 프로그램 상태 보존 -> PCB(Process Control Block), PC(Program Counter) 등
+4. 인터럽트 서비스 루틴 실행: 인터럽트 처리 코드
+5. 상태 복구
+6. 중단 프로그램 실행 재개
+
+
+
+이 과정에서 유저모드에서 커널모드로 넘어갈 떄 컨텍스트 스위칭이 되면서 오버헤드가 발생하는데 이로 인해 시스템 상 지연이 발생한다.
+하지만 고성능 어플리케이션을 할 때 이 지연은 꽤나 치명적일 것이다.
+그래서 위와 같이 DMA(Direct Memory Access)라는 기술을 사용하게 됐다.
+예를들어, DirectX라는 것이 있는데 이는 게임을 할 때 이러한 컨텍스트 스위칭 되는 부분을 건너뛰어 직접 드라이버까지 가는 방식이 있다.
+이렇듯 DirectX처럼 인터럽트 시 컨텍스트 스위칭으로 인한 오버헤드가 발생하면서 지연이 발생하는데 이걸 해소하는 것이 DMA인 것이다.
+정리하자면, [DMA는 RAM에 일정 부분을 예약해 불필요한 컨텍스트 스위칭을 스킵해 오버헤드 방지 및 지연을 획기적으로 줄이는 방식이다.](https://en.wikipedia.org/wiki/Direct_memory_access#:~:text=DMA%20(%20Direct%20Memory%20Access%20)%EB%8A%94%20%ED%8A%B9%EC%A0%95%20%ED%95%98%EB%93%9C%EC%9B%A8%EC%96%B4%20%ED%95%98%EC%9C%84%20%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%9D%B4%20%EC%A4%91%EC%95%99%20%EC%B2%98%EB%A6%AC%20%EC%9E%A5%EC%B9%98%20(CPU)%20%EC%99%80%20%EB%8F%85%EB%A6%BD%EC%A0%81%EC%9C%BC%EB%A1%9C%20%EC%A3%BC%20%EC%8B%9C%EC%8A%A4%ED%85%9C%20%EB%A9%94%EB%AA%A8%EB%A6%AC%20%EC%97%90%20%EC%95%A1%EC%84%B8%EC%8A%A4%ED%95%A0%20%EC%88%98%20%EC%9E%88%EB%8F%84%EB%A1%9D%20%ED%95%98%EB%8A%94%20%EC%BB%B4%ED%93%A8%ED%84%B0%20%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%9D%98%20%EA%B8%B0%EB%8A%A5%EC%9E%85%EB%8B%88%EB%8B%A4%20.)
+
+
+
+
diff --git a/contents/posts/os/3/img.png b/contents/posts/os/3/img.png
new file mode 100644
index 0000000..61552c6
Binary files /dev/null and b/contents/posts/os/3/img.png differ
diff --git a/contents/posts/os/3/img_1.png b/contents/posts/os/3/img_1.png
new file mode 100644
index 0000000..59f1ceb
Binary files /dev/null and b/contents/posts/os/3/img_1.png differ
diff --git a/contents/posts/os/3/img_2.png b/contents/posts/os/3/img_2.png
new file mode 100644
index 0000000..3c39dda
Binary files /dev/null and b/contents/posts/os/3/img_2.png differ
diff --git a/contents/posts/os/3/img_3.png b/contents/posts/os/3/img_3.png
new file mode 100644
index 0000000..9da3b71
Binary files /dev/null and b/contents/posts/os/3/img_3.png differ
diff --git a/contents/posts/os/3/index.md b/contents/posts/os/3/index.md
new file mode 100644
index 0000000..69fda68
--- /dev/null
+++ b/contents/posts/os/3/index.md
@@ -0,0 +1,106 @@
+---
+title: "3. 프로세스"
+description:
+date: 2025-09-08
+update: 2025-09-08
+tags:
+ - 운영체제
+series: "운영체제"
+---
+
+## 프로세스란?
+
+
+
+컴퓨팅에서 프로세스란 운영체제로부터 메모리 공간을 할당받아 실행 중인 프로그램의 [인스턴스](https://ko.wikipedia.org/wiki/%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4_(%EC%BB%B4%ED%93%A8%ED%84%B0_%EA%B3%BC%ED%95%99)#:~:text=%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4(instance)%EB%8A%94%20%ED%95%B4%EB%8B%B9%20%ED%81%B4%EB%9E%98%EC%8A%A4%EC%9D%98%20%EA%B5%AC%EC%A1%B0%EB%A1%9C%20%EC%BB%B4%ED%93%A8%ED%84%B0%20%EC%A0%80%EC%9E%A5%EA%B3%B5%EA%B0%84%EC%97%90%EC%84%9C%20%ED%95%A0%EB%8B%B9%EB%90%9C%20%EC%8B%A4%EC%B2%B4%EB%A5%BC%20%EC%9D%98%EB%AF%B8%ED%95%9C%EB%8B%A4.)를 의미합니다.
+여기서 논하는 프로그램이란, 일반적으로 하드 디스크와 같은 저장장치에 저장되어 있는 실행 코드를 뜻합니다.
+
+## 프로세스의 메모리 공간
+
+프로세스는 다음 4개의 메모리 영역으로 구성되고 [가상 메모리](https://ko.wikipedia.org/wiki/%EA%B0%80%EC%83%81_%EB%A9%94%EB%AA%A8%EB%A6%AC#:~:text=%EA%B0%80%EC%83%81%20%EB%A9%94%EB%AA%A8%EB%A6%AC%20%EB%98%90%EB%8A%94%20%EA%B0%80%EC%83%81%20%EA%B8%B0%EC%96%B5%20%EC%9E%A5%EC%B9%98(%EB%AC%B8%ED%99%94%EC%96%B4%3A%20%EA%B0%80%EC%83%81%EA%B8%B0%EC%96%B5%EA%B8%B0%2C%20virtual%20memory%2C%20virtual%20storage)%EB%8A%94%20%EB%A9%94%EB%AA%A8%EB%A6%AC%20%EA%B4%80%EB%A6%AC%20%EA%B8%B0%EB%B2%95%EC%9D%98%20%ED%95%98%EB%82%98%EB%A1%9C%2C%20%EC%BB%B4%ED%93%A8%ED%84%B0%20%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%97%90%20%EC%8B%A4%EC%A0%9C%EB%A1%9C%20%EC%9D%B4%EC%9A%A9%20%EA%B0%80%EB%8A%A5%ED%95%9C%20%EA%B8%B0%EC%96%B5%20%EC%9E%90%EC%9B%90%EC%9D%84%20%EC%9D%B4%EC%83%81%EC%A0%81%EC%9C%BC%EB%A1%9C%20%EC%B6%94%EC%83%81%ED%99%94%ED%95%98%EC%97%AC%5B1%5D%20%EC%82%AC%EC%9A%A9%EC%9E%90%EB%93%A4%EC%97%90%EA%B2%8C%20%EB%A7%A4%EC%9A%B0%20%ED%81%B0%20(%EC%A3%BC)%20%EB%A9%94%EB%AA%A8%EB%A6%AC%EB%A1%9C%20%EB%B3%B4%EC%9D%B4%EA%B2%8C%20%EB%A7%8C%EB%93%9C%EB%8A%94%20%EA%B2%83%EC%9D%84%20%EB%A7%90%ED%95%9C%EB%8B%A4.%5B2%5D%20%EA%B0%81%20%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8%EC%97%90%20%EC%8B%A4%EC%A0%9C%20%EB%A9%94%EB%AA%A8%EB%A6%AC%20%EC%A3%BC%EC%86%8C%EA%B0%80%20%EC%95%84%EB%8B%8C%20%EA%B0%80%EC%83%81%EC%9D%98%20%EB%A9%94%EB%AA%A8%EB%A6%AC%20%EC%A3%BC%EC%86%8C%EB%A5%BC%20%EC%A3%BC%EB%8A%94%20%EB%B0%A9%EC%8B%9D%EC%9D%B4%EB%8B%A4.) 공간에 독립적으로 형성됩니다.
+
+- 코드 영역(Code) : 프로그램 실행 코드가 적재되는 영역입니다. 읽기 모드만 지원합니다.
+- 데이터 영역(Data) : 프로세스의 초기화 된 데이터들인 전역 변수와 정적 변수들이 적재되는 영역입니다.
+- 힙 영역(Heap) : 런타임 동안 생성된 데이터를 보관하기 위해 동적으로 할당받는 영역입니다.
+- 스택 영역(Stack) : 지역변수, 매개변수, 리턴 값, 복귀 주소 등이 저장되는 영역입니다.
+
+이렇게 영역이 나눠진 이유는 최대한 중복적인 데이터를 방지하여 메모리 사용량을 줄이는데 목적이 있습니다.
+
+> 예를 들면, 코드에서 공통으로 사용하는 부분을 전역 변수로 지정하는 행위와 같다.
+
+## PCB(프로세스 제어 블록)
+
+커널은 시스템 전체에 대해 레지스터에 하나의 프로세스 테이블을 두고 모든 프로세스의 정보를 관리합니다.
+여기서의 프로세스 정보는 해당 프로세스를 실행하기 위해 필요한 정보들로 컨텍스트라고 부릅니다.
+여기서 프로세스의 상태에 따라 프로세스를 교체하는 작업인 컨텍스트 스위칭 작업 이루어 지는데,
+이와 같은 상황에서 여러 프로세스를 관리하기 위해 각 프로세스들에 대해 식별이 가능해야 관리가 가능하기에 해당 프로세스의 정보가 필요합니다.
+
+예를 들어, 인터럽트가 발생해서 자원을 할당받은 프로세스가 대기 상태가 되고 다른 프로세스를 실행 상태로 올릴 때
+대기 중인 프로세스를 나중에 다시 수행하기 위해 대기 중인 프로세스의 상태와 같은 정보를 알아야 할 것입니다.
+
+운영체제의 커널은 이러한 이유로 활성된 프로세스를 관리하기 위해 해당 프로세스에 대한 정보를 PCB(프로세스 제어 블록)이라는 데이터 구조에 저장합니다.
+("PCB는 운영 체제가 프로세스를 표현한 것이다."라는 말도 있습니다.)
+
+
+
+> PCB는 해당 프로세스가 실행되면 생성되어 종료 시 제거가 되는데 이 과정에서 PCB의 삽입 및 삭제가 용이한 연결 리스트(Linked List) 방식으로 관리됩니다.
+
+## Process Metadata
+
+그럼 PCB에는 어떤 정보가 담겨있을까요?
+PCB에는 아래와 같은 프로세스의 메타데이터들이 담겨져 있습니다.
+
+- 프로세스 번호(PID, Process ID): 각 프로세스의 고유 식별 번호입니다.(PPID: 부모 프로세스 ID)
+- 프로세스 상태(Process State): 프로세스가 현재 어떤 상태인지를 나타내는 정보(new, ready, running, waiting, end)입니다.
+- 프로그램 카운터(PC, Program Counter): 이 프로세스에서 실행될 다음 명령어의 주소를 가리키는 포인터(주소)입니다.
+- 레지스터 상태(Register State): 프로세스의 레지스터 값 세트로, 프로세스를 다시 실행할 때 현재 상태를 복원하는 데 사용됩니다.
+- 스케줄링 정보(Scheduling Information): CPU 시간 스케줄링에 대한 정보입니다.
+- 메모리 관리 정보 (Memory Management Information): 프로세스의 메모리 할당과 사용에 관한 정보입니다.
+- 입출력 상태 (I/O Status): 프로세스가 입출력 작업을 수행 중인 경우, 해당 상태 정보 및 장치 정보입니다.
+
+## 프로세스 상태
+
+운영체제의 커널은 프로세스를 관리하기 위해 프로세스 정보를 알아야 해서 PCB를 생성하는 것을 알았습니다.
+여기서 커널의 프로세스 관리는 프로세스 상태를 관리하는 것이기도 합니다.
+
+프로세스 상태는 위에서 언급한대로 프로세스가 현재 어떤 상태인지를 나타내는 정보로,
+프로세스의 상태에 따라 CPU를 할당하거나 대기 상태로 전환하는 등의 작업이 이루어집니다.
+프로세스 상태는 일반적으로 다음과 같은 상태로 구분됩니다.
+
+
+
+- New(생성) : 프로세스는 저장장치에서 메모리로 로드되어 생성됩니다. 이후 커널은 메모리를 할당하고 PCB를 생성하고 프로세스 테이블에 등록합니다. 실행 준비를 마치면 ready 상태로 전이됩니다.
+- Ready(준비) : 프로세스가 CPU를 사용하고 있지는 않지만 언제든지 사용할 수 있는 상태로, 해당 상태의 프로세스들은 커널에 있는 준비 큐([우선순위 큐](https://ko.wikipedia.org/wiki/%EB%B9%84%EC%9C%A8_%EB%8B%A8%EC%A1%B0_%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81))에 들어갑니다. 스케줄러가 컨텍스트 스위칭을 수행할 때, 준비 큐에서 우선순위가 높은 프로세스가 CPU 스케줄링에 따라 리소스를 할당받아 running 상태로 전이(디스패치)됩니다.
+- Running(실행) : 프로세스가 CPU를 차지하여 명령어들이 실행되고 있는 상태입니다. 할당된 시간을 모두 사용(타임아웃)했다면 타이머 인터럽트가 발생되어 준비 상태로 전이되고, 입출력 요청이나 자원 요청 등으로 인해 대기 상태로 전이될 수도 있습니다.
+- Waiting(대기) : 프로세스 실행 도중 입출력 완료(주된 원인)와 같은 수신 등을 대기하는 상태를 말합니다.
+- End(=terminated, 종료) : 프로세스의 실행이 종료된 상태입니다. 이떄, PCB와 프로세스의 메모리를 해제 또는 정리합니다.
+
+## 프로세스 계층 구조
+
+프로세스는 실행 도중 시스템 콜을 통해 다른 프로세스를 생성할 수 있습니다.
+이때 시스템 콜을 호출한 프로세스를 부모 프로세스, 생성된 프로세스를 자식 프로세스라 합니다.
+
+> 서로 다른 프로세스라 서로 다른 PID를 가집니다.
+> 일부 운영체제에서는 자식 프로세스의 PCB에 부모 프로세스의 PID (PPID)가 기록되기도 합니다.
+
+프로세스 생성 기법은 복제와 교체 과정을 통한 방식을 사용합니다.
+
+
+
+흐름의 시작인 부모 프로세스는 fork(복제) 시스템 콜을 통해 자신의 복사본을 자식 프로세스로 생성합니다.
+자식 프로세스는 exec(교체) 시스템 콜을 통해 자신의 메모리 공간을 다른 프로그램으로 교체합니다.
+이때, 자식 프로세스의 메모리 공간을 새로운 프로그램으로 덮어쓰게 합니다.(코드/데이터는 내용만 바꾸고, 나머지는 초기화)
+자식 프로세스가 exec 시스템 콜을 호출하지 않을 경우, 부모 프로세스와 자식 프로세스는 같은 코드를 병행하여 실행하는 프로세스가 됩니다.
+이러한 과정을 통해 프로세스는 계층 구조를 이루어 관리할 수 있습니다.
+
+많은 운영체제에서는 이처럼 프로세스를 낳는 계층적인 구조로써 프로세스들을 관리합니다.
+컴퓨터가 부팅될 때 실행되는 최초의 프로세스가 자식 프로세스들을 생성하고,
+생성된 자식 프로세스들이 새로운 프로세스들을 낳는 형식으로 여러 프로세스가 동시에 실행되는 것입니다.
+
+## 프로세스 간 통신
+
+앞서 언급했던 것처럼 프로세스는 서로 독립된 메모리 공간을 가지므로, 프로세스끼리는 서로의 영역에 접근 또는 간섭할 수 없습니다.
+이러한 이유로 통신이 필요할 경우, [IPC](https://ko.wikipedia.org/wiki/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4_%EA%B0%84_%ED%86%B5%EC%8B%A0#:~:text=%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%20%EA%B0%84%20%ED%86%B5%EC%8B%A0(Inter%2DProcess%20Communication%2C%20IPC)%EC%9D%B4%EB%9E%80%20%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EB%93%A4%20%EC%82%AC%EC%9D%B4%EC%97%90%20%EC%84%9C%EB%A1%9C%20%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%A5%BC%20%EC%A3%BC%EA%B3%A0%EB%B0%9B%EB%8A%94%20%ED%96%89%EC%9C%84%20%EB%98%90%EB%8A%94%20%EA%B7%B8%EC%97%90%20%EB%8C%80%ED%95%9C%20%EB%B0%A9%EB%B2%95%EC%9D%B4%EB%82%98%20%EA%B2%BD%EB%A1%9C%EB%A5%BC%20%EB%9C%BB%ED%95%9C%EB%8B%A4.)를 통해 프로세스 간에 통신을 할 수 있습니다.
+IPC에는 공유 메모리를 이용한 통신과 파일을 통한 프로세스 간 통신 이렇게 두 가지 방법이 있습니다.
+
+> IPC 통신 시, 프로세스 간 데이터를 동기화하고 보호하기 위해 [세마포어](https://ko.wikipedia.org/wiki/%EC%84%B8%EB%A7%88%ED%8F%AC%EC%96%B4)와 [뮤텍스](https://ko.wikipedia.org/wiki/%EC%83%81%ED%98%B8_%EB%B0%B0%EC%A0%9C)를 사용합니다.
\ No newline at end of file
diff --git a/contents/posts/os/4/img.png b/contents/posts/os/4/img.png
new file mode 100644
index 0000000..c48a254
Binary files /dev/null and b/contents/posts/os/4/img.png differ
diff --git a/contents/posts/os/4/img_1.png b/contents/posts/os/4/img_1.png
new file mode 100644
index 0000000..8cdb98b
Binary files /dev/null and b/contents/posts/os/4/img_1.png differ
diff --git a/contents/posts/os/4/img_2.png b/contents/posts/os/4/img_2.png
new file mode 100644
index 0000000..00c615c
Binary files /dev/null and b/contents/posts/os/4/img_2.png differ
diff --git a/contents/posts/os/4/img_3.png b/contents/posts/os/4/img_3.png
new file mode 100644
index 0000000..3bdb369
Binary files /dev/null and b/contents/posts/os/4/img_3.png differ
diff --git a/contents/posts/os/4/index.md b/contents/posts/os/4/index.md
new file mode 100644
index 0000000..baca002
--- /dev/null
+++ b/contents/posts/os/4/index.md
@@ -0,0 +1,85 @@
+---
+title: "4. 쓰레드 "
+description:
+date: 2025-09-08
+update: 2025-09-08
+tags:
+ - 운영체제
+series: "운영체제"
+---
+
+## 쓰레드란?
+
+쓰레드는 프로세스를 구성하는 실행 흐름의 단위를 의미합니다.
+
+
+
+그래서 하나의 프로세스는 1개 이상의 쓰레드를 가집니다.
+이로 인해 하나의 프로세스에서 여러 작업을 동시에 수행할 수 있습니다.
+
+> #### 사용자 수준 쓰레드와 커널 수준 쓰레드의 차이
+> 사용자 수준 쓰레드란, 라이브러리를 통해 구현한 쓰레드를 의미합니다.
+> 쓰레드와 관련된 모든 행위를 사용자 영역에서 하기 때문에,
+> 커널은 사용자 수준 쓰레드의 존재를 알지 못하고 쓰레드 교환에 개입하지 않습니다.
+> 커널 수준 쓰레드란, 커널이 직접 생성하고 관리하는 쓰레드를 의미합니다.
+
+## 쓰레드의 메모리 공간
+
+같은 프로세스의 쓰레드는 프로세스로부터 각각의 스택을 나눠갖지만 Code, Data, Heap 메모리 영역을 공유합니다.
+하지만, 쓰레드 ID, 스택, PC나 레지스터 같은 쓰레드 컨텍스트에 대해서는 각기 다른 값을 가지고 있습니다.
+
+
+
+이렇게 각자의 PC, 레지스터, 스택을 가지고 있기에 쓰레드마다 독립적으로 실행할 수 있습니다.
+
+여기서 중요한 점은 프로세스의 쓰레드들은 실행에 필요한 최소한의 정보(PC, 레지스터, 스택)만을 유지한 채
+프로세스 자원을 공유하며 실행된다는 점입니다.
+
+## TCB(쓰레드 제어블록)
+
+쓰레드 또한 프로세스의 PCB(프로세스 제어 블록)처럼 TCB(쓰레드 제어 블록)을 통해 관리됩니다.
+TCB는 각 쓰레드에 위치하고, 커널은 TCB를 통해 쓰레드를 관리합니다.
+
+그럼 TCB에는 어떤 정보가 담겨있을까요?
+TCB에는 아래와 같은 쓰레드의 메타데이터들이 담겨져 있습니다.
+
+
+
+- 쓰레드 번호(TID, Thread ID): 각 쓰레드의 고유 식별 번호입니다.
+- 스택 포인터 (Stack Pointer): 쓰레드가 존재하는 프로세스의 PCB에 대한 포인터
+- 프로그램 카운터(PC, Program Counter): 이 쓰레드에서 실행될 다음 명령어의 주소를 가리키는 포인터(주소)입니다.
+- 쓰레드 상태(Thread State): 쓰레드가 현재 어떤 상태인지를 나타내는 정보(new, ready, running, waiting, end)입니다.
+- 레지스터 상태(Register State): 쓰레드의 레지스터 값 세트입니다.
+
+각 프로세스에 대한 중요 정보를 강조하는 특정 정보가 쓰레드 제어 블록에 저장됩니다.
+
+## 프로세스와 쓰레드의 차이
+
+프로세스는 각각 독립된 메모리 영역(Code, Data, Heap, Stack)을 할당받고 고유 프로세스 ID를 가지는 특성으로 인해,
+프로세스끼리는 서로의 영역에 접근할 수 없습니다.
+그래서 한 프로세스가 다른 프로세스의 자원에 접근하려면 IPC(inter-process communication)을 사용해야 합니다.
+
+하지만, 쓰레드는 IPC와 같은 별도의 통신 방법 없이도 앞서 언급한 것처럼 프로세스의 Code, Data, Heap 메모리 영역을 공유합니다.
+
+이처럼 프로세스들 사이의 통신에 대한 어려움 해소 및 빠른 컨텍스트 스위칭으로 인해 쓰레드가 프로세스보다 더 가벼운 실행 단위로 사용됩니다.
+이로 인해 현대에 와서 운영체제의 실행단위는 프로세스에서 쓰레드로 바뀌어 가고 있습니다.
+
+## 동시성 환경에서의 차이
+
+동시성 환경에서는 어떤지 알아볼까요?
+여러 프로세스를 동시에 실행하는 멀티 프로세스와 한 프로세스에서 여러 쓰레드를 동시에 실행하는 멀티 쓰레드가 있습니다.
+
+
+
+
+여기서 가장 큰 차이점은 프로세스끼리는 기본적으로 공유하지 않지만, 쓰레드끼리는 같은 프로세스 내의 자원을 공유한다는 점입니다.
+
+즉, 멀티 프로세스는 여러 프로세스를 동시에 실행해 각각의 독립적인 프로세스 간 자원을 공유하지 않기 때문에 프로세스 간 통신 (IPC) 방식을 써야 합니다.
+또한, 메모리에 동일한 내용들이 중복해서 존재하기 때문에 메모리에도 부담이 될 수 있습니다.
+그러나 한편으로는 자원을 공유하지 않는 덕분에 하나의 프로세스에 문제가 생겨도 다른 프로세스들에는 문제가 발생하지 않는다는 장점이 있기도 합니다.
+
+반면, 멀티 쓰레드는 실행에 필요한 최소한의 정보(PC, 레지스터, 스택)만을 유지한 채 프로세스 자원을 공유하며 실행되기에
+커널의 개입 없이 쓰레드간 통신을 할 수 있고, 메모리에도 부담이 덜합니다.
+또한 fork로 인한 생성이 공유하는 부분을 제외한 부분만 복사하면 되기 때문에 프로세스보다 빠릅니다.(쓰레드가 접근하는 공유 데이터에 대해 동기화 작업을 수행해야 합니다)
+
+하지만, 하나의 쓰레드에 문제가 생기면 같은 프로세스 내의 다른 쓰레드들에도 문제가 발생할 수 있다는 단점이 있습니다.
diff --git a/contents/posts/os/5/index.md b/contents/posts/os/5/index.md
new file mode 100644
index 0000000..c8206bb
--- /dev/null
+++ b/contents/posts/os/5/index.md
@@ -0,0 +1,134 @@
+---
+title: "5. CPU 스케줄링"
+description:
+date: 2025-09-12
+update: 2025-09-12
+tags:
+ - 운영체제
+series: "운영체제"
+---
+
+## 기아 상태와 CPU 스케줄링
+
+프로세스들은 실행할 때 컴퓨터 자원을 사용하는데, 이때 CPU도 사용합니다.
+그런데 만약 하나의 프로세스가 오랜 시간 동안 CPU를 점유하거나,
+너무 짧은 텀동안만 실행되는 경우 공정하지 못한 방법으로 자원을 할당하게 될 것이고
+이는 시스템의 효율적이지 못한 방법으로 돌아가게 하는 길을 초래할 수 있을 겁니다.
+이를 컴퓨팅에서는 기아 현상이라고 하는데,
+이로 인해 프로세스들에게 CPU 자원 할당을 배분해주는 CPU 스케줄링이 개발되었고,
+운영체제에 반드시 필요로 하게 되었습니다.
+
+> 기아 현상에 대한 대표적인 해결 방법은 에이징 기법을 이용하는 것입니다.
+> 오랫동안 대기한 프로세스의 우선순위에 대해 가중치를 주어,
+> 처음에 우선순위가 낮아도 언젠가는 우선순위가 높아져 기아 현상을 막을 수 있습니다.
+> 이와 같이 CPU 스케줄링에서는 이러한 문제 해결을 위한 다양한 방식들이 있습니다.
+
+## 프로세스 우선 순위
+
+스케줄링을 지정하는 것은 순서를 지정하는 것과 같습니다.
+그런데 어떻게 프로세스들 간의 순위를 공정하게 지원하고 있을까요?
+
+### 순차방식
+
+가장 단순하게 생각해보면 요청이 들어온 순서대로 할당하는 방식입니다.
+그러나 이 방식은 빨리 처리해야 하는 프로세스가 있을 수 있는 상황에서 대응하지 못한다는 것입니다.
+
+예시로 CPU를 많이 사용하는 프로세스가 I/O 작업을 하는 프로세스 보다 늦게 들어올 경우,
+순서상으로는 뒤에 있어야 하지만, CPU 자원을 할당한다는 측면에서 볼 떄에는 앞 순위로 두는 것이 효울적일 것입니다.
+
+### 우선순위 지정 방식
+
+위 순차적인 방식이 아닌, 별도의 우선순위를 지정하는 방식도 있습니다.
+이때, 우선순위에 대한 정보는 PCB에 저장이 됩니다.
+
+이로 인해 프로세스의 중요도에 맞게 프로세스가 CPU를 이용할 수 있도록 운영체제가 부여하는 것이 우선순위이며,
+운영체제는 PCB를 기반으로 어떤 프로세스가 CPU를 얼마나 사용하게 될 것인지 등을 결정합니다.
+
+프로세스 우선순위는 간단한 명령어나 프로그램 등으로 확인이 가능한데,
+일부 우선순위의 경우에는 사용자가 직접 설정 가능한 것도 있습니다.
+
+### 스케줄링 큐
+
+프로세스가 여러 개일 경우, 다음 CPU 자원을 이용할 프로세스를 선택하기 위해 매번 모든 프로세스들의 PCB를 다 뒤져보는 것은 매우 비효율적일 것입니다.
+또한, CPU 말고도, 메모리, 입출력 장치를 사용하고자 하는 경우에도 비슷한 상황을 겪을 것입니다.
+
+때문에 운영체제는 어떤 자원을 이용하고자 할 때 대기 하는 스케줄링 큐를 활용하고 있습니다.
+
+이때, 큐라고 해서 반드시 선입선출(FIFO)에 국한되지 않습니다.
+
+## 선점형 스케줄링과 비선점형 스케줄링
+
+스케줄링 방식에는 선점형 스케줄링과 비선점형 스케줄링 방식이 있습니다.
+
+### 선점형 스케줄링
+
+선점형 스케줄링은 현재 CPU를 사용 중인 프로세스로부터 CPU 자원을 뺴앗아 요청한 프로세스에 할당하는 방법입니다.
+어느 한 프로세스의 자원 독점을 막고 프로세스에 골고루 자원을 배분할 수 있으나, 그 만큼 컨텍스트 스위칭 과정에서 오버헤드가 발생할 수 있습니다.
+
+### 비선점형 스케줄링
+
+비선점형 스케줄링은 현재 CPU를 사용 중인 프로세스의 작업이 끝날 때까지 기다리는 방식입니다.
+
+선점형 스케줄링과 반대되는 개념으로, 컨텍스트 스위칭에서 발생하는 오버헤드가 적지만, 한편으로는 모든 프로세스가 골고루 자원을 이용하기 어렵습니다.
+
+## CPU 스케줄링 알고리즘
+
+선점형 스케줄링과 비선점형 스케줄링을 기반으로 다양한 CPU 스케줄링 알고리즘이 있습니다.
+
+### 선입 선처리 스케줄링
+
+FCFS(First Come First Served) 스케줄링으로, 준비 큐에 삽입된 순서대로 처리하는 비선점 스케줄링 방식입니다.
+CPU를 먼저 요청한 프로세스부터 CPU를 할당합니다.
+이로 인해 프로세스들이 기다리는 시간이 매우 길어질 수 있는 부작용이 있으며,
+이를 convoy effect, 호위 효과라고 합니다.
+
+### 최단 작업 우선 스케줄링
+
+SJF(Shortest Job First) 스케줄링으로,
+사용 시간이 긴 프로세스를 나중에 실행하고,
+시간이 짧은 프로세스를 먼저 실행함으로써 평균 대기 시간을 줄일 수 있습니다.
+이 알고리즘은 기본적으로는 비선점형 스케줄링 방식에 속하지만,
+선점형과 비선점형 스케줄링 방식으로 모두 가능합니다.
+
+### 라운드 로빈 스케줄링
+
+RR(Round Robin) 스케줄링으로,
+선입 선처리 스케줄링과 시분할 시스템의 타임 슬라이스(time slice) 개념이 결합된 방식입니디.
+정해진 타임 슬라이스만큼의 시간 동안 돌아가며 CPU를 이용하게 하는 선점형 스케줄링입니다.
+
+### 최소 잔여 시간 우선 스케줄링
+
+SRT(Shortest Remaining Time) 스케줄링으로,
+최단 작업 우선 스케줄링과 라운드 로빈 스케줄링이 결합된 형태입니다.
+정해진 시간만큼 CPU를 이용하되,
+다음으로 CPU를 사용할 프로세스로는 남은 작업 시간이 가장 적은 프로세스를 선택합니다.
+
+### 우선순위 스케줄링
+
+프로세스들에 우선순위를 부여하고, 우선순위가 높은 프로세스부터 실행하는 방식입니다.
+우선순위가 같은 프로세스들은 선입 선처리 스케줄링으로 돌아가고,
+최단 작업 우선 스케줄링이나 최소 잔여 시간 스케줄링은 포괄적인 의미에서 우선순위 스케줄링에 속한다고 할 수 있습니다.
+
+### 다단계 큐 스케줄링
+
+멀티 레벨 큐 스케줄링으로도 불리는데, 우선순위 스케줄링의 발전된 형태입니다.
+우선순위 별로 준비 큐를 여러 개 사용하고, 우선순위가 높은 큐에 있는 프로세스를 먼저 실행합니다.
+우선순위가 높은 큐가 비어 있다면, 그 다음 우선순위 큐에 있는 프로세스를 처리합니다.
+이러한 방식은 프로세스 유형별로 우선순위를 구별하게 하여 관리가 쉬워집니다.
+큐 별로 타임 슬라이스를 여러 개 지정할 수도 있고, 큐마다 다른 스케줄링 알고리즘을 사용할 수도 있습니다.
+기본적으로 큐 간 이동이 불가능하기 때문에, 우선순위가 낮은 프로세스는 계속해서 우선순위가 낮을 수 밖에 없고,
+그로 인해 기아 현상을 겪을 수도 있습니다.
+
+### 다단계 피드백 큐 스케줄링
+
+멀티 레벨 피드백 큐 스케줄링으로도 불리는 이 방식은 다단계 큐 스케줄링의 발전된 형태로,
+큐 간 이동이 가능합니다.
+새로 준비 상태로 된 프로세스가 있으면 가장 우선순위가 높은 큐에 삽입합니다.
+일정 시간 즉, 타임 슬라이스 만큼 CPU를 사용할 수 있는데,
+만약 작업이 끝나지 않았다면,
+그때 우선순위가 다음으로 높은 곳에 삽입을 합니다.
+작업을 많이 있는 프로세스일수록 우선순위가 점점 낮아지게 되고,
+따라서 CPU 집중 프로세스는 상대적으로 우선순위가 낮아지고, 입출력 집중 프로세스는 높아지게 될 겁니다.
+일정 시간 이상 낮은 우선순위에서 기다리고 있던 프로세스가 있었다면 이 프로세스의 우선순위를 점차 높임으로써 기아 현상을 방지할 수 있습니다.
+다단계 피드백 큐 스케줄링은 CPU 사용 시간이 길면 우선순위가 점점 낮아지고, 동시에 어떤 프로세스가 낮은 우선순위 큐에서 너무 오래 기다리면 우선순위를 높일 수도 있습니다.
+다단계 피드백 큐 스케줄링은 복잡하지만, CPU 스케줄링의 가장 일반적인 형태로 알려져 있습니다.
diff --git a/contents/posts/os/6/img.png b/contents/posts/os/6/img.png
new file mode 100644
index 0000000..8bd031d
Binary files /dev/null and b/contents/posts/os/6/img.png differ
diff --git a/contents/posts/os/6/index.md b/contents/posts/os/6/index.md
new file mode 100644
index 0000000..08c77a8
--- /dev/null
+++ b/contents/posts/os/6/index.md
@@ -0,0 +1,205 @@
+---
+title: "6. 프로세스 동기화"
+description:
+date: 2025-09-19
+update: 2025-09-19
+tags:
+ - 운영체제
+series: "운영체제"
+---
+
+## 프로세스 동기화
+
+컴퓨터에서는 여러 프로세스들이 서로 협력하기 위해 동시에 같은 자원(주소 공간)을 공유하며 실행하기도 합니다.
+이러한 상황에서 사용되는 자원에서는 원자성과 일관성을 보장해야 합니다.
+이를 위해 운영체제에서는 프로세스 동기화라는 기법을 사용합니다.
+
+> 컴퓨터 과학에서 동기화는 합의에 도달하거나 특정 작업 순서를 커밋하기 위해 특정 지점에 합류하거나 핸드셰이킹하도록 여러 프로세스를 조정하는 작업이다. - [wikipedia](https://ko.wikipedia.org/wiki/%EB%8F%99%EA%B8%B0%ED%99%94_(%EC%BB%B4%ED%93%A8%ED%84%B0_%EA%B3%BC%ED%95%99)#:~:text=%EC%BB%B4%ED%93%A8%ED%84%B0%20%EA%B3%BC%ED%95%99%EC%97%90%EC%84%9C%20%EB%8F%99%EA%B8%B0%ED%99%94(synchronization)%EB%8A%94%20%ED%95%A9%EC%9D%98%EC%97%90%20%EB%8F%84%EB%8B%AC%ED%95%98%EA%B1%B0%EB%82%98%20%ED%8A%B9%EC%A0%95%20%EC%9E%91%EC%97%85%20%EC%88%9C%EC%84%9C%EB%A5%BC%20%EC%BB%A4%EB%B0%8B%ED%95%98%EA%B8%B0%20%EC%9C%84%ED%95%B4%20%ED%8A%B9%EC%A0%95%20%EC%A7%80%EC%A0%90%EC%97%90%20%ED%95%A9%EB%A5%98%ED%95%98%EA%B1%B0%EB%82%98%20%ED%95%B8%EB%93%9C%EC%85%B0%EC%9D%B4%ED%82%B9%ED%95%98%EB%8F%84%EB%A1%9D%20%EC%97%AC%EB%9F%AC%20%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EB%A5%BC%20%EC%A1%B0%EC%A0%95%ED%95%98%EB%8A%94%20%EC%9E%91%EC%97%85%EC%9D%B4%EB%8B%A4.)
+
+프로세스 동기화란 프로세스들 사이의 수행시기를 맞추는 것을 의미합니다.
+프로세스 동기화는 실행 순서 제어를 위한 동기화와 상호베제를 위한 동기화로 구분할 수 있습니다.
+
+> 현대에는 대부분 쓰레드 기준으로 동기화 컨텍스트 스위칭이 발생해서 쓰레드 동기화라고 부르기도 합니다.
+> 하지만 공유되는 환경에서 실행의 흐름을 갖는 모든 것들이 동기화의 대상이기에 엄격하게 구분을 짓진 않는 것 같습니다.
+
+### 실행 순서 제어를 위한 동기화
+
+실행 순서 제어를 위한 동기화는 프로세스들이 특정 순서에 따라 실행되어야 하는 경우에 사용됩니다.
+예를 들어, 프로세스 A가 프로세스 B보다 먼저 실행되어야 하는 경우, A가 완료된 후에 B가 실행되도록 제어하는 것입니다.
+
+### 상호배제를 위한 동기화
+
+상호배제를 위한 동기화는 여러 프로세스가 동시에 공유 자원에 접근하는 것을 방지하기 위해 사용됩니다.
+예를 들어, 두 개의 프로세스가 동시에 같은 파일에 접근하여 데이터를 수정하는 경우, 데이터의 일관성이 깨질 수 있습니다.
+이러한 상황을 방지하기 위해, 한 프로세스가 공유 자원에 접근하는 동안 다른 프로세스는 접근하지 못하도록 제어하는 것입니다.
+
+## 공유 자원과 임계 구역
+
+공유 자원(shared resource)이란 여러 프로세스가 동시에 접근할 수 있는 자원을 의미합니다.
+예를 들어, 메모리 공간, 파일, 입출력 장치 등이 공유 자원에 해당합니다.
+임계 구역(critical section)이란 이러한 공유 자원에 접근하는 코드의 부분을 의미합니다.
+즉, 공유 자원에 접근하는 코드 영역을 임계 구역이라고 합니다.
+
+## 경쟁 상태
+
+임계 구역에 대한 동시 접근은 예상치 못한 동작이나 오류 동작을 초래해 자원의 일관성을 해칠 수 있습니다.
+이러한 상황을 경쟁 상태 즉, 레이스 컨디션(race condition)이라고 합니다.
+
+
+
+운영체제는 임계 구역에서 발생하는 이러한 경쟁 상태를 방지하기 위해 다음과 같은 기법을 원칙 하에 동기화를 구현합니다.
+
+- 상호 배제(mutual exclusion) : 한 프로세스가 임계 구역에 진입했다면 다른 프로세스는 임계 구역에 들어올 수 없습니다.
+- 진행(process) : 임계 구역에 어떤 프로세스도 진입하지 않았다면 임계 구역에 진입하고자 하는 프로세스는 들어갈 수 있어야 합니다.
+- 유한 대기(bounded waiting) : 한 프로세스가 임계 구역에 진입하고 싶다면 그 프로세스는 언젠가는 임계 구역에 들어올 수 있어야 합니다. 임계 구역에 들어오기 위해 무한정 대기해서는 안 됩니다
+
+## 동기화 기법
+
+이제 실행 순서 제어와 상호 배제를 위한 동기의화 실제 적용 기법에 대해 알아보겠습니다.
+
+### 뮤텍스 락
+
+뮤텍스 락(mutex lock)은 임계 구역에 동시에 접근하지 않도록 하는 상보 배체를 위한 동기화 기법입니다.
+임계 구역에 진입하는 프로세스는 자신이 현재 임계 구역에 있음을 알리기 위해 뮤텍스 락을 이용해서 임계 구역에 락을 걸 수 있습니다.
+다른 프로세스는 임계 구역에 락이 걸려 있다면 기다리고, 그렇지 않다면 임계 구역에 진입할 수 있게 됩니다.
+
+뮤텍스 락은 프로세스들이 공유하는 `lock` 전역변수와
+임계 구역에 락을 거는 `acquire` 함수,
+그 락을 해제하는 역할인 `release` 함수로 구성됩니다.
+
+```java
+class Mutex {
+ private boolean lock = false;
+ public void acquire() {
+ while (lock) {
+ // busy waiting
+ }
+ lock = true;
+ }
+ public void release() {
+ lock = false;
+ }
+}
+```
+
+> 여기서 `busy waiting`이란 프로세스가 임계 구역에 진입하기 위해 반복적으로 `lock`를 확인하는 것을 의미합니다.
+> 이런 행위는 CPU 자원을 낭비를 유발합니다.
+
+이렇게 구현하게 되면 프로세스는 임계 구역에 락이 되어있을 경우 계속해서 락이 해제되기를 기다리게 됩니다.
+락이 해제되어 임계 구역에 진입할 수 있게 되면 락을 건 후 임계 구역에 진입하여 작업을 진행하게 됩니다.
+그리고 다시 임계 구역에서 빠져나올 때 락을 해제하여 다른 프로세스가 임계 구역에 진입할 수 있도록 합니다.
+뮤텍스 락은 이런 방식으로 임계 구역에 동시에 접근하는 것을 방지하여 임계구역을 보호할 수 있습니다.
+
+### 세마포어
+
+세마포어(semaphore)는 뮤텍스 락보다 더 일반화된 동기화 기법으로,
+실행 순서 제어를 위한 동기화와 상호 배제를 위한 동기화 모두에 사용할 수 있습니다.
+뮤텍스 락은 임계 구역에 하나의 프로세스만 접근할 수 있도록 하지만,
+세마포어는 여러 프로세스가 동시에 접근할 수 있도록 허용할 수 있습니다.
+
+> 사실 세마포어의 종류에는 이진 세마포와 카운팅 세마포어가 있습니다.
+> 하지만 이진 세마포어는 뮤텍스 락과 동일한 기본 구현을 사용하는 락 메커니즘로서,
+> 이 글에서는 카운팅 세마포어에 대해 설명하고자 합니다.
+
+#### 상호배제를 위한 세마포어
+
+세마포어는 임계 구역에 동시에 접근할 수 있는 프로세스의 수를 나타내는 정수형 전역 변수 `S`와
+임계 구역에 진입하기 위해 `S`를 감소시키는 `wait` 함수,
+임계 구역에서 빠져나올 때 `S`를 증가시키는 `signal` 함수로 구성됩니다.
+
+```java
+class Semaphore {
+ private int S;
+ public Semaphore(int S) {
+ this.S = S;
+ }
+ public void wait() {
+ while (S <= 0) {
+ // busy waiting
+ }
+ S--;
+ }
+ public void signal() {
+ S++;
+ }
+}
+```
+
+코드를 보면 바쁜 대기(busy waiting)이 뮤텍스에서 본 거 처럼 존재하는 것을 알 수 있습니다.
+세마포어는 이런 상황에서 CPU 자원을 낭비하는 것을 방지하기 위해,
+바쁜 대기 대신 프로세스를 대기 상태로 전환하는 방법을 사용합니다.
+
+```java
+class Semaphore {
+ private int S;
+ private Queue queue = new LinkedList<>();
+
+ public Semaphore(int S) {
+ this.S = S;
+ }
+
+ public synchronized void acquire(Process p) {
+ S--;
+ if (S < 0) {
+ queue.add(p);
+ p.sleep(); // 블로킹
+ }
+ }
+
+ public synchronized void release() {
+ S++;
+ if (S <= 0) {
+ Process p = queue.poll();
+ if (p != null) {
+ p.wakeUp();
+ }
+ }
+ }
+}
+```
+
+이렇게 구현하게 되면 프로세스는 임계 구역에 진입하기 위해 `acquire` 함수를 호출합니다.
+`S`가 0보다 작아지면 임계 구역에 진입할 수 없으므로, 프로세스는 대기 큐에 추가되고 대기 상태로 전환됩니다.
+그리고 임계 구역에서 빠져나올 때 `release` 함수를 호출하여 `S`를 증가시키고,
+대기 큐에 있는 프로세스 중 하나를 깨워서 임계 구역에 진입할 수 있도록 합니다.
+이런 방식으로 세마포어는 .
+
+#### 실행 순서 제어를 위한 세마포어
+
+세마포어는 실행 순서 제어를 위한 동기화에도 사용할 수 있습니다.
+프로세스 $P_1$가 프로세스 $P_2$보다 먼저 실행되어야 하는 경우를 예로 들어보겠습니다.
+전역 변수 `S`를 0으로 초기화하고,
+먼저 실행할 프로세스 $P_1$ 뒤에 `signal` 함수를 호출하여 `S`를 1로 증가시킵니다.
+그리고 나중에 실행할 프로세스 $P_2$ 앞에는 `wait` 함수를 호출합니다.
+이렇게 하면 $P_2$가 먼저 진입해도 `wait` 함수로 인해 $P_1$ 프로세스 먼저 실행되고, 그 다음에 $P_2$가 실행되도록 제어할 수 있습니다.
+즉, $P_1$와 $P_2$의 실행되는 순서에 차이가 있더라도 항상 $P_1$가 먼저 실행되도록 보장할 수 있습니다.
+
+### 모니터
+
+이처럼 세마포어는 뮤텍스 락보다 더 일반화된 동기화 기법이지만,
+매번 임계 구역에 진입할 때마다 `wait`와 `signal` 함수를 호출해야 하므로 번거롭고,
+코드가 복잡해질 수 있습니다.
+또한, `wait`와 `signal` 함수를 호출하는 순서가 잘못되거나 중복해서 사용한 경우 예기치 못한 상황이 발생할 수 있습니다.
+이를 해결하기 위해 모니터(monitor)라는 고수준의 동기화 기법이 개발되었습니다.
+
+#### 상호배제를 위한 모니터
+
+모니터는 공유 자원과 공유 자원에 접근하기 위한 인터페이스를 하나의 추상 데이터 타입으로 캡슐화한 것입니다.
+모니터를 통해 공유 자원에 접근하고자 하는 프로세스를 큐에 삽입하고,
+큐에서 프로세스를 꺼내어 공유 자원을 사용할 수 있도록 합니다.
+즉, 모니터에 진입하기 위한 큐를 만들고,
+모니터 안에 항상 하나의 프로세스만 존재하도록 보장여 상호 배제를 위한 동기화를 구현합니다.
+
+##### 실행 순서 제어를 위한 모니터
+
+모니터는 모니터에 진입하도록 하기 위한 상호 배제를 위한 큐와
+`wait`가 호출되어 실행 중단된 프로세스가 대기하는 큐,
+그리고 조건 변수(condition variable)를 이용하여 실행 순서 제어를 위한 동기화도 구현할 수 있습니다.
+
+> 조건 변수란 실행 순서를 제어하기 위해 wait()와 signal()을 호출할 수 있는 특별한 변수입니다.
+
+세마포어와 마찬가지로 모니터에서도 `wait`와 `signal` 함수를 사용하는 것을 알 수 있는데,
+동작은 유사하지만, 자체적인 값을 가지는 세마포어와 달리,
+모니터의 조건 변수는 자체적인 값을 가지지 않고,
+프로세스를 큐에 삽입하고 꺼내는 역할만 합니다.
+
diff --git a/contents/posts/os/7/img.png b/contents/posts/os/7/img.png
new file mode 100644
index 0000000..1ff02c9
Binary files /dev/null and b/contents/posts/os/7/img.png differ
diff --git a/contents/posts/os/7/index.md b/contents/posts/os/7/index.md
new file mode 100644
index 0000000..87f0b7c
--- /dev/null
+++ b/contents/posts/os/7/index.md
@@ -0,0 +1,108 @@
+---
+title: "7. 교착 상태"
+description:
+date: 2025-09-19
+update: 2025-09-19
+tags:
+ - 운영체제
+series: "운영체제"
+---
+
+## 교착 상태
+
+교착 상태(deadlock)란 둘 이상의 프로세스가 서로 자원을 점유한 채로 다른 프로세스가 점유한 자원을 기다리며 무한정 대기하는 상태를 의미합니다.
+
+
+
+이러한 상황에서는 프로세스들이 서로 자원을 점유하고 있기 때문에 아무도 진행할 수 없게 됩니다.
+그럼 교착 상태는 언제 발생할까요?
+교착 상태 발생 조건은 다음과 같습니다.
+조건 중 하나라도 만족하지 않는다면 교착상태가 발생하지 않지만,
+아래 조건이 모두 만족될 때 교착 상태가 발생할 가능성이 생깁니다.
+
+- 점유와 대기(hold and wait): 자원을 점유하고 있으면서 다른 자원을 기다리는 상태
+- 상호 배제(mutual): 한 프로세스가 사용하는 자원을 다른 프로세스가 사용할 수 없는 상태
+- 비선점(non-preemptive): 어떤 프로세스도 다른 프로세스의 자원을 강제로 뺴앗지 못하는 상태
+- 원형 대기(circular wait): 자원을 기다리는 프로세스들이 순환되는 원형으로 연결되어 있는 상태
+
+운영체제는 교착 상태를 예방, 회피, 탐지 및 회복하는 방법으로 교착 상태 문제를 해결합니다.
+
+## 교착 상태 예방
+
+교착 상태 예방(prevention)은 교착 상태 발생 조건 중 하나라도 만족하지 않도록,
+교착 상태 조건인 점유와 대기, 상호 배제, 비선점, 원형 대기 중 하나를 제거한다는 의미입니다.
+
+먼저 상호 배제 조건을 제거하는 방법이 있습니다.
+이는 현실적으로 불가능합니다.
+상호 배제를 제거한 다는 건 모든 자원을 공유하게 된다는 의미인데,
+이는 동기화를 할 때 문제가 발생할 수 있습니다.
+
+다음 방법은 점유와 대기 조건을 제거하는 방법인데,
+특정 프로세스에 자원을 모두 할당하거나,
+아예 할당하지 않는 방법입니다.
+이 방법은 당장 자원이 필요해도 기다릴 수 밖에 없는 프로세스와
+사용되지 않으면서 오랫동안 할당되는 자원을 양산시켜
+자원의 활용도를 떨어뜨릴 수 있습니다.
+
+또 다른 방법으로는 비선점 조건을 제거하는 방법이 있습니다.
+이 방법은 어떤 프로세스가 자원을 할당받았을 때,
+다른 프로세스가 그 자원을 필요로 한다면,
+할당받은 자원을 강제로 빼앗아 다른 프로세스에 할당하는 방법입니다.
+이 방법은 자원을 강제로 빼앗기 때문에
+프로세스가 작업을 완료하지 못하고 중단될 수 있습니다.
+그렇기에 프린터 같이 선점이 불가능한 자원에는 적용하지 못하고,
+선점이 가능한 자원에 한에 효과적입니다.
+그래서 이 방법 또한 범용성이 떨어져 현실적으로 적용하기 어렵습니다.
+
+마지막으로 원형 대기 조건을 없애는 방법이 있습니다.
+원형 대기 조건을 없애는 방법은 자원에 순서를 매겨서
+오름차순으로 낮은 순서의 자원만 할당받을 수 있도록 하는 방법입니다.
+이 방법이 앞선 방법들에 비해 가장 현실적으로 적용할 수 있는 방법입니다.
+하지만 컴퓨터 시스템 내에 존재하는 수많은 자원에 순서를 매기는 것이 쉽지 않고,
+각 자원에 순서를 어떻게 할 건지에 따라 특정 자원의 활용률이 달라집니다.
+
+## 교착 상태 회피
+
+교착 상태 회피(avoidance)는 자원 할당 시 교착 상태가 발생하지 않도록,
+미리 판단하고 자원을 할당하다가 교착 상태의 위험이 있으면 자원 할당을 멈추는 방법입니다.
+
+교착 상태 회피에 대해 이해하기 위해 다음 용어들을 알아야 합니다.
+
+- 안전 순서열(safe sequence): 시스템이 교착 상태 없이 모든 프로세스를 완료할 수 있는 순서열
+- 안전 상태(safe state): 시스템이 안전 순서열을 가지고 있는 상태
+- 불안전 상태(unsafe state): 시스템이 안전 순서열을 가지고 있지 않은 상태
+
+예를 들어 $P_1$, $P_2$, $P_3$ 프로세스가 동시에 자원을 요청한 상황에서,
+$P_3 \to P_2 \to P_1$ 순서로 자원을 할당하면 교착 상태가 발생하지 않는다고 가정하면,
+$P_3 \to P_2 \to P_1$가 안전 순서열이 되는 것입니다.
+이 안전 순서열이 있는 상태를 안전 상태라고 하고, 없는 상태가 불완전 상태라고 합니다.
+
+운영체제는 교착 상태를 회피하기 위해 시스템 상태가 안전 상태에서 벗어나지 않는 경우에만 자원을 할당합니다.
+
+## 교착 상태 탐지 및 회복
+
+교착 상태 탐지(detection) 및 회복(recovery)는 자원을 할당하다가 교착 상태를 탐지하고,
+탐지된 교착 상태를 회복하는 방법입니다.
+회복에는 선점을 통햐 회복하는 방식과 프로세스 강제 종료를 통해 회복하는 방식이 있습니다.
+
+먼저, 선점을 통한 회복 방식은 교착 상태에 빠진 프로세스 중 하나를 선택하여,
+그 프로세스가 점유하고 있는 자원을 강제로 빼앗아 다른 프로세스에 할당하는 방법입니다.
+이 방법은 선점이 가능한 자원에만 적용할 수 있습니다.
+또한, 어떤 프로세스를 선택할지에 대한 기준이 명확하지 않기 때문에
+적절한 프로세스를 선택하지 못하면 오히려 교착 상태가 더 심해질 수 있습니다.
+
+다음으로 프로세스 강제 종료를 통한 회복 방식은
+교착 상태에 빠진 프로세스들을 모두 강제 종료시키는 방법과
+교착 상태가 해결 될 때까지 하나씩 강제 종료시키는 방법이 있습니다.
+
+모두 강제 종료시키는 방법은 강제 종료된 프로세스가 작업을 완료하지 못하고 중단될 수 있습니다.
+그리고 작업 내용을 잃을 위험이 있습니다.
+
+하나씩 강제 종료시키는 방법은 강제 종료 후,
+교착 상태가 해결 되었는지 확인하는 과정에서 오버헤드가 발생합니다.
+
+이처럼 선점이 불가능한 자원에도 적용할 수 있지만,
+교착 상태 탐지 및 회복 방법은 교착 상태를 예방하거나 회피하는 방법에 비해
+교착 상태가 발생한 후에야 문제를 해결할 수 있고,
+시스템의 성능에 큰 영향을 미칠 수 있습니다.
+따라서, 교착 상태 탐지 및 회복 방법은 교착 상태가 자주 발생하지 않는 시스템에서만 사용되는 것이 일반적입니다.
\ No newline at end of file
diff --git a/contents/posts/os/8/img.png b/contents/posts/os/8/img.png
new file mode 100644
index 0000000..435b2ac
Binary files /dev/null and b/contents/posts/os/8/img.png differ
diff --git a/contents/posts/os/8/img_1.png b/contents/posts/os/8/img_1.png
new file mode 100644
index 0000000..e238b16
Binary files /dev/null and b/contents/posts/os/8/img_1.png differ
diff --git a/contents/posts/os/8/img_2.png b/contents/posts/os/8/img_2.png
new file mode 100644
index 0000000..cf4d217
Binary files /dev/null and b/contents/posts/os/8/img_2.png differ
diff --git a/contents/posts/os/8/index.md b/contents/posts/os/8/index.md
new file mode 100644
index 0000000..fc43086
--- /dev/null
+++ b/contents/posts/os/8/index.md
@@ -0,0 +1,110 @@
+---
+title: "8. 메모리 관리"
+description:
+date: 2025-09-22
+update: 2025-09-22
+tags:
+ - 운영체제
+series: "운영체제"
+---
+
+## 절대 주소와 상대 주소
+
+메모리는 크게 2가지 영역으로 나눌 수 있습니다.
+하나는 운영체제가 사용하는 커널 영역이고, 다른 하나는 사용자 프로세스가 사용하는 사용자 영역입니다.
+운영체제는 커널 영역을 사용하고, 사용자 프로세스는 사용자 영역을 사용합니다.
+
+
+
+운영체제는 중요한 역할을 하기 때문에 사용자가 운영체제 영역을 침범하지 못하도록 분리하여 메모리를 사용합니다.
+사용자 프로세스는 메모리에 들어올 때 운영체제 영역으로 지정된 영역 이외의 사용자 영역에 저장되어야 합니다.
+만약 운영체제 영역이 100번지까지 있으므로 사용자 프로세스는 101번지부터 들어올 수 있다.
+
+이렇게 메모리에 접근할 때 사용하는 것이 메모리 주소입니다.
+메모리는 1Byte 크기로 나뉘어 각 영역은 메모리 주소로 구분을 하는데,
+보통 첫번째 영역을 0번지로 지정하여 시작합니다.
+CPU는 메모리에 저장된 데이터를 읽거나 쓸 때 메모리 주소 레지스터(MAR, Memory Address Register)에 메모리 주소를 지정하여 접근합니다.
+
+이러한 메모리 주소는 절재 주소(absolute address)와 상대 주소(relative address)로 나뉘는데,
+절대 주소는 실제 메모리의 주소 공간을 가리키는 것으로 메모리 관리자 입장에서 사용하는 주소입니다.
+즉, MAR이 사용하는 주소로 컴퓨터에 삽입된 메모리의 실제 주소를 의미합니다.
+상대 주소는 메모리 공간에서 사용자 영역이 시작되는 베이스 주소를 0번지로 변경해서 사용하는 주소 지정 방식입니다.
+즉, 사용자 프로세스 입장에서 메모리 공간을 바라본 주소이고, 절대 주소와 관계없이 항상 0번지부터 시작합니다.
+
+
+
+> 주소를 2개로 나눈 이유는 사용자 입장에서 절대 주소를 사용하게 되면 불편하고 위험하기 때문이다.
+> 절대 주소를 사용하게 되면 사용자 프로세스 입장에서는 운영체제 영역은 사용할 수 없는 공간이지만,
+> 매번 운영체제 영역을 확인해야 하는 불편함이 존재한다.
+> 하지만 상대 주소를 사용하면 상대 주소가 운영체제 영역의 위치를 알 필요가 없고,
+> 주소가 항상 0번지부터 시작하기 떄문에 편리해진다.
+> 또한, 절대 주소를 사용하게 되면 사용자가 운영체제 영역의 주소를 실수나 고의적인 조작으로
+> 접근할 수 있는 위험의 소지가 있게 된다.
+
+이렇게 사용자 프로세스 입장에서 사용하는 상대 주소와 실제로 메모리 공간을 가리키는 메모리 관리자가 쓰는 절대 주소로 나뉜다면,
+메모리 접근 시 상대 주소를 절대 주소로 변환하는 과정이 필요합니다.
+상대 주소를 절대 주소로 변환하는 과정은 다음과 같습니다.
+1. 운영체제는 사용자 프로세스가 메모리에 적재될 때, 운영체제 영역이 끝나는 주소를 베이스 레지스터(base register)에 저장합니다.
+2. CPU가 사용자 프로세스의 상대 주소를 MAR에 지정하여 메모리에 접근하려고 하면, CPU는 MAR에 지정된 상대 주소에 베이스 레지스터에 저장된 값을 더하여 절대 주소로 변환합니다.
+3. 변환된 절대 주소를 이용하여 메모리에 접근합니다.
+
+> 프로세스에 메모리 공간을 할당하는 방식은 연속 메모리 할당 방식입니다.
+
+## 스와핑
+
+스와핑(swapping)은 현재 실행되지 않는 프로세스들을 보조기억 장치의 일부 영역으로 쫓아내고,
+메모리에 생긴 빈 공간에 새로운 프로세스를 적재 시키는 방법입니다.
+
+- 스왑 영역(swap space): 프로세스들이 쫓겨나서 머무는 보조기억장치의 일부 영역
+- 스왑 아웃(swap out): 현재 실행되지 않는 프로세스가 메모리에서 스왑 영역으로 옮겨지는 것
+- 스왑 인(swap in): 스왑 영역에 있던 프로세스를 다시 메모리로 옮겨오는 것
+
+여기서 스왑 아웃되었던 프로세스가 다시 스왑 인이 될 때는 이전 물리 주소와 다른 주소에 적재될 수 있습니다.
+
+
+
+스와핑을 이용하면 프로세스들이 요구하는 메모리 공간 크기가 실제 메모리 크기보다
+크더라도 모든 프로세를 동시 실행할 수 있습니다.
+
+## 메모리 할당
+
+프로세스는 메모리의 빈 공간에 할당되어야 합니다.
+빈 공간이 여러개 있다면 어떤 공간에 메모리를 할당할지에 대한 방법으로 아래의 세 가지가 있습니다.
+
+- 최초 적합(first-fit): 최초 적합은 운영체제가 메모리 내의 빈 공간을 순서대로 탐색하다 적재할 수 있는 공간을 발견하면,
+ 그 공간에 프로세스를 배치하는 방식입니다. 적재할만한 공간을 찾으면 바로 할당하기 때문에 다른 방식보다 탐색 시간이 적고, 빠른 할당이 가능합니다.
+- 최적 적합(best-fit): 운영체제가 빈 공간을 모두 탐색해본 뒤, 적재 가능한 가장 작은 공간에 할당하는 방식입니다.
+- 최악 적합(worst-fit): 운영체제가 빈 공간을 모두 탐색해본 뒤, 적재 가능한 가장 큰 공간에 할당하는 방식입니다.
+
+## 단편화
+
+단편화(external fragmentation)은 주기억장치에 프로그램을 할당하고 반남하는 과정에서 발생하는 사용되지 않는 작은 조각 공간을 뜻합니다.
+주기억장치 상에서 빈번하게 기억장소가 할당되고 반납됨에 따라 기억 장소들이 조각들오로 나누어지는 현상을 뜻하기도 합니다.
+메모리 할당 방식인 최초 적합, 최적 적합, 최악 적합 모두 단편화를 피할 수는 없습니다.
+
+단편화에는 내부 단편화와 외부 단편화가 있습니다.
+
+### 내부 단편화
+
+내부 단편화(internal fragmentation)은 주기억장치 내 사용자 영역이 실행 프로그램보다 커서,
+프로그램의 사용 공간을 할당 후 사용되지 않고 남게 되는 현상을 말합니다.
+예를 들어, 100MB의 메모리에 80MB 크기의 프로세스를 올리게 되면 20MB가 남게 되는데
+이렇게 적은 크기의 잔여 메모리가 발생해 해당 메모리를 사용할 수 해당 메모리를 사용할 수 없게 되는 것을 내부 단편화라고 합니다.
+
+### 외부 단편화
+
+외부 단편화(external fragmentation)은 남아있는 총 메모리 공간이 요청한 메모리 공간보다 크지만,
+남아있는 공간이 연속적(contiguous)이지 않아 발생하는 현상입니다.
+예를 들어, 남아있는 공간이 50MB로 된 2개가 있다고 가정하고 올려야하는 프로세스의 크기가 80MB라면,
+남아있는 공간은 총 100MB로 요청한 메모리 공간 80MB보다 크지만,
+남아있는 공간이 연속적이지 않아서 프로세를 할당할 수 없게 됩니다.
+이로 인해 남아있는 메모리 공간이 낭비되게 되는 문제가 발생하게 됩니다.
+이를 외부 단편화라고 합니다.
+
+외부 단편화를 해결하기 위해 압축 기법을 사용할 수 있습니다.
+압축 기법은 주기억장치 내 분산되어 있는 단편화된 공간들을 통합하여 하나의 커다란 빈 공간을 통합하여,
+하나의 커다란 빈 공간을 만드는 작업을 말합니다.
+
+하지만 압축이 좋은 점만 있는 것은 아닙니다.
+작은 빈 공간들을 하나로 모으는 동안 시스템은 하던 작업을 멈추어야 하고,
+어떤 프로세스를 어떻게 움직여야 오버헤드를 최소화화며 압축할 수 있는지에 대한 명확한 방법을 결정하기가 어렵습니다.
diff --git a/contents/posts/os/9/img.png b/contents/posts/os/9/img.png
new file mode 100644
index 0000000..8c521ea
Binary files /dev/null and b/contents/posts/os/9/img.png differ
diff --git a/contents/posts/os/9/img_1.png b/contents/posts/os/9/img_1.png
new file mode 100644
index 0000000..5a5e869
Binary files /dev/null and b/contents/posts/os/9/img_1.png differ
diff --git a/contents/posts/os/9/img_2.png b/contents/posts/os/9/img_2.png
new file mode 100644
index 0000000..0d4d539
Binary files /dev/null and b/contents/posts/os/9/img_2.png differ
diff --git a/contents/posts/os/9/index.md b/contents/posts/os/9/index.md
new file mode 100644
index 0000000..2bee5c4
--- /dev/null
+++ b/contents/posts/os/9/index.md
@@ -0,0 +1,263 @@
+---
+title: "9. 가상 메모리"
+description:
+date: 2025-09-23
+update: 2025-09-23
+tags:
+ - 운영체제
+series: "운영체제"
+---
+
+## 연속 메모리 할당의 문제점
+
+연속 메모리 할당의 문제점은 단편화 문제 외에도
+물리 메모리의 크기보다 큰 프로세스의 실행이 불가한 점이 있습니다.
+
+예를 들어, RAM 용량이 4GB인데 프로세스 크기가 5GB면 실행할 수 없는 것을 의미합니다.
+하지만 가상 메모리(virtual memory)를 이용하면 이게 가능합니다.
+또한 외부 단편화 문제도 해결할 수 있습니다.
+가상 메모리는 실행하고자 하는 프로그램을 일부만 메모리에 적재하여,
+실제 메모리 크기보다 더 큰 프로세스를 실행할 수 있게 해줍니다.
+가상 메모리 관리 기법에는 페이징과 세그멘테이션이 있습니다.
+
+## 페이징
+
+메모리 연속 할당에서 외부 단편화가 발생했던 근본적 이유는
+다른 크기의 프로세스가 메모리에 연속으로 할당되었기 때문입니다.
+페이징(paging)은 메모리와 프로세스를 일정한 단위로 자르고,
+이를 메모리에 불연속적으로 할당할 수 있도록 하여
+외부 단편화가 발생하지 않도록 할 수 있습니다.
+
+페이징의 기본 개념은 프로세스의 논리 주소 공간을 페이지(page)라는 일정 단위로 자르고,
+메모리 물리 주소 공간을 프레임(frame)이라는 페이지와 동일한 일정한 단위로 자른 뒤,
+페이지를 프레임에 할당하는 가상 메모리 관리 방식입니다.
+
+### 페이징에서 스와핑
+
+페이징에서도 스와핑이 사용 가능한데,
+페이징을 사용하는 시스템에서 프로세스 전체가 스왑 인, 스왑 아웃 되는 것이 아닌,
+페이지 단위로 스왑 인, 스왑 아웃이 가능합니다.
+즉, 메모리에 적재될 필요가 없는 페이지들은 보조기억 장치로 스왑 아웃되고,
+실행에 필요한 페이지들은 메모리로 스왑 인됩니다.
+
+이렇게 스와핑을 함으로써 한 프로세스를 실행하기 위해 프로세스 전체가 메모리에 적재될 필요가 없게 되었습니다.
+즉, 프로세스를 이루는 페이지 중 실행에 필요한 일부 페이지만을 메모리에 적재하고,
+당장 실행에 필요하지 않은 페이지들은 보조기억장치에 남겨둘 수 있게 되었습니다.
+이와 같은 방식을 통해 물리 메모리 크기보다 더 큰 프로세스도 실행할 수 있게 되었습니다.
+
+### 페이지 테이블
+
+페이징을 사용하면
+프로세스를 이루는 페이지가 어느 프레임에 적재되어 있는지 CPU가 알기가 어렵다.
+프로세스가 메모리에 불연속적으로 배치되어 있다면,
+CPU 입장에서 이를 순차적으로 실행할 수가 없다.
+CPU 입장에서는 다음에 실행할 명령어 위치를 찾기가 어려워집니다.
+
+이를 해결하기 위해 페이지 테이블(page table)을 사용하게 되었습니다.
+페이지 테이블이란 실제 메모리 주소인 물리 주소에 불연속적으로 배치되더라도,
+CPU가 인식하는 논리 주소에는 연속적으로 배치될도록 하는 방식입니다.
+즉, 페이지 번호와 프레임 번호를 매핑시킨 표라고 할 수 있습니다.
+
+이렇게 하면 물리 주소상에서는 프로세스들이 분산되어 저장되어 있더라도,
+CPU 입장에서는 연속적으로 보일 수 있다.
+즉, 프로세스들이 메모리에 분산되어 저장되어 있더라도 CPU는 논리 주소를 그저 순차적으로 실행하면 됩니다.
+
+> 페이징은 외부 단편화는 해결하지만, 내부 단편화는 막을 수 없습니다.
+> 페이징은 프로세스의 논리 주소공간을 페이지라는 일정한 크기로 자른다. 하지만 모든 프로세스가 페이지 크기에 딱 맞게 잘리는 것은 아닙니다.
+> 예를 들어, 페이지 크기가 10KB인데 프로세스 크기가 108KB라면 마지막 페이지는 2KB가 남습니다.
+> 이러한 메모리 낭비는 페이징에서는 해결할 수 없습니다.
+
+### 페이지 테이블 베이스 레지스터
+
+페이지 테이블 베이스 레지스터(PTBR)은 각기 페이지 테이블이 있고, 각 페이지 테이블은 CPU 내의 PTBR이 가리키는 주소에 저장됩니다.
+즉, PTBR은 각 프로세스의 페이지 테이블이 적재된 주소를 가리키는 레지스터입니다.
+각 프로세스들의 페이지 테이블 정보들은 각 프로세스 PCB에 저장되어 있습니다.
+
+### TLB
+
+페이지 테이블을 메모리에 두면 메모리 접근 시간이 두 배로 늘어납니다.
+왜냐하면 메모리에 있는 페이지 테이블을 보고
+테이블을 통해 알게 된 프레임에 접근하기 위해
+이렇게 총 두 번의 메모리 접근이 필요하기 때문입니다.
+이와 같은 문제를 해결하기 위해 TLB(Translation Lookaside Buffer)를 사용합니다.
+TLB는 페이지 테이블의 일부를 캐시 메모리에 저장하는 고속 캐시입니다.
+참조 지역성에 근거해 페이지 테이블의 일부를 가져와 저장합니다.
+CPU가 발생한 논리 주소에 대한 페이지 번호가 TLB에 있을 경우 TLB 히트라고 하고,
+이 경우 페이지가 적재된 프레임을 알기 위해 메모리에 접근할 필요가 없습니다.
+하지만, CPU가 발생한 논리 주소에 대한 페이지 번호가 TLB에 없을 경우 TLB 미스라고 하고,
+이 경우는 페이지가 적재된 프레임을 알기 위해 메모리 내의 페이지 테이블에 접근해야 합니다.
+
+### 페이징에서의 주소 변환
+
+하나의 페이지 혹은 프레임은 여러 주소를 포괄하고 있습니다.
+그렇기 떄문에 특정 주소에 접근하려면 어떤 페이지에 혹은 프레임에 접근하고 싶은지
+그리고 접근하려는 주소가 그 페이지 혹은 프레임으로부터 얼마나 떨어져 있는지 알아야 합니다.
+이를 위해 페이징 시스템에서 모든 논리 주소는 페이지 번호(page number)와 페이지 오프셋(page offset)으로 나누어집니다.
+$(page \ number, offset)$으로 이뤄진 논리 주소는 페이지 테이블을 통해 $(frame \ number, offset)$으로 이뤄진 물리 주소로 변환됩니다.
+
+> 페이지와 프레임은 단위가 같기 때문에 논리 주소의 변위와 물리 주소의 변위는 같습니다.
+
+### 페이지 테이블 엔트리
+
+페이지 테이블 안에 있는 각각의 행(row)들을 페이지 테이블 엔트리(page table entry)라고 합니다.
+페이지 테이블 엔트리에 담기는 정보는 페이지 번호와 프레임 번호뿐만 아니라
+유효 비트, 보호 비트, 참조 비트, 수정 비트 등이 담겨져 있습니다.
+
+#### 유효 비트
+
+여기서 유효 비트(valid bit)는 현재 해당 페이지에 접근 가능한지 여부를 나타냅니다.
+프레임 번호 다음으로 중요한 정보입니다.
+유효 비트가 1이면 해당 페이지가 메모리에 적재되어 있음을 의미하고,
+유효 비트가 0이면 해당 페이지가 메모리에 적재되어 있지 않음을 의미합니다.
+유효 비트가 0인 페이지에 접근하려고 하면 페이지 폴트(page fault)가 발생합니다.
+CPU가 페이지 폴트를 처리하는 과정은 하드웨어 인터럽트를 처리한느 과정과 유사합니다.
+
+1. CPU는 기존의 작업 내역을 백업합니다.
+2. 페이지 폴트 처리 루틴을 실행합니다.
+3. 페이지 처리 루틴은 원하는 페이지를 메모리로 가져온 뒤 유효 비트를 1로 변경해 줍니다.
+4. 페이지 폴트를 처리했다면 이제 CPU는 해당 페이지에 접근할 수 있게 됩니다.
+
+#### 보호 비트
+
+보호 비트(protection bit)는 페이지 보호 기능을 위해 존재하는 비트입니다.
+읽고 쓰기가 모두 가능한지, 읽기만 가능한지 나타냅니다.
+보호 비트가 0이면 읽기만 가능하고,
+보호 비트가 1이면 읽기와 쓰기가 모두 가능함을 의미합니다.
+프로세스를 이루는 요소 중 코드 영역은 읽기 전용 영역인데,
+이러한 읽기 전용 페이지에 쓰기 시도를 하면 운영체제가 이를 감지하고 막아줍니다.
+이와 같은 방식으로 페이지 단위로 보호 기능을 구현할 수 있습니다.
+
+#### 참조 비트
+
+참조 비트(reference bit)는 CPU가 이 페이지에 접근한 적이 있는지 여부를 나타냅니다.
+참조 비트가 1이면 적재 이후에 CPU가 이 페이지에 접근한 적이 있음을 의미하고,
+참조 비트가 0이면 적재 이후에 CPU가 이 페이지에 접근한 적이 없음을 의미합니다.
+이러한 참조 비트는 페이지 교체 알고리즘에서 사용됩니다.
+
+#### 수정 비트
+
+수정 비트(modified bit $or$ dirty bit)는 bit해당 페이지에 데이터를 쓴 적이 있는지 없는지 수정 여부를 나타냅니다.
+해당 페이지에 데이터를 쓴 적이 있는지 없는지 수정 여부를 나타냅니다.
+페이지가 메모리에서 사라질 때 보조기억장치에 쓰기 작업을 해야하는지, 할 필요가 없는지를 판단하는 데 사용됩니다.
+수정 비트가 1이면 해당 페이지에 데이터를 변경된 적이 있음을 의미하고,
+수정 비트가 0이면 해당 페이지에 데이터를 변경된 적이 없음을 의미합니다.
+수정 비트가 1인 페이지가 메모리에서 사라질 때는
+해당 페이지를 보조기억장치에 다시 써줘야 합니다.
+
+CPU는 메모리를 읽는 것뿐만 아니라 메모리에 값을 쓰기도 하는데, 한 번도 수정된 적이 없는 페이지가 스왑 아웃될 경우,
+어차피 같은 페이지가 보조 기억 장치에 저장되어 있기 때문에 아무런 추가 작업을 하지 않아도 됩니다.
+반대로 수정된 적이 있는 경우, 페이지가 스왑 아웃될 경우,
+변경된 값을 보조기억장치에 기록하는 작업이 추가되어야 하기 때문에 이러한 작업이 필요한지 아닌지를 판단하기 위해 수정 비트가 사용됩니다.
+
+## 요구 페이징
+
+처음부터 모든 페이지를 메모리에 적재하는 것이 아니라,
+프로세스가 필요로 하는 페이지를 그때그때 메모리에 적재하는 방식을 요구 페이징(demand paging)이라고 합니다.
+
+요구 페이징은 아래의 과정으로 이루어집니다.
+1. CPU가 특정 페이지에 접근하는 명령어를 실행합니다.
+2. 해당 페이지가 현재 메모리에 있을 경우 즉, 유효 비트가 1일 경우 CPU는 페이지가 적재된 프레임에 접근합니다.
+3. 해당 페이지가 현재 메모리에 없을 경우 즉, 유효 비트가 0일 경우 페이지 폴트가 발생합니다.
+4. 페이지 폴트 처리 루틴은 해당 페이지를 메모리로 적재하고 유효 비트를 1로 설정합니다.
+5. 다시 1번을 수행합니다.
+
+### 순수 요구 페이징
+
+순수 요구 페이징(pure demand paging)은 아무런 페이지도 메모리에 적재하지 않은 채 일단 프로세스를 실행하는 방식입니다.
+프로세스의 모든 페이지가 메모리에 적재되지 않은 상태에서 실행되기 때문에
+프로세스의 첫 명령어부터 페이지 폴트가 발생하게 됩니다.
+어느 정도 시간이 지난 후부터는 페이지 폴트가 발생 빈도가 줄어들게 됩니다.
+
+### 요구 페이징이 안정적으로 작동하려면
+
+요구 페이징 시스템이 안정적으로 작동하려면 필연적으로 페이지 교체와 프레임 할당을 해결해야 합니다.
+
+## 페이지 교체 알고리즘
+
+요구 패이징 기법으로 페이지를 적재하다 보면 언젠간 메모리가 가득 차게 됩니다.
+메모리가 가득 찬 상황에서 당장 실행에 필요한 페이지를 적재하려면 기존에 적재된 페이지를
+보조기억장치로 내보내야 합니다.
+이떄, 기존에 적재된 페이지 중에 어떤 페이지를 내보낼지 결정하는 알고리즘을 페이지 교체 알고리즘(page replacement algorithm)이라고 합니다.
+교체 알고리즘의 성능을 한단할 때는 페이지 폴트의 횟수에 대한 페이지 부재율(page fault rate)을 사용합니다.
+페이지 폴트가 자주 발생하면 보조기억장치에 접근하는 횟수가 증가한다는 뜻이기 때문입니다.
+
+그렇기에 페이지 교체 알고리즘을 제대로 이해하려면 페이지 폴트 횟수를 알 수 있어야 합니다.
+그리고 페이지 폴트 횟수는 페이지 참조열(page reference string)을 통해 알 수 있습니다.
+페이지 참조열은 CPU가 참조하는 페이지들 중 연속된 페이지를 생략한 페이지 열을 의미합니다.
+예를 들어 $2 2 2 3 5 5 5 3 7$이라는 연속된 페이지 열이 있다고 하면,
+페이지 참조열은 $2 3 5 3 7$이 됩니다.
+연속된 페이지를 생략하는 이유는 중복된 페이지를 참조하는 행위는 페이지 폴트를 발생시키지 않기 때문입니다.
+페이지 교체 알고리즘을 평가할 때 고려할 것은 오직 페이지 폴트의 발생 횟수이기 때문이고,
+어차피 페이지 폴트가 일어나지 않을 연속된 페이지에 대한 참조느 고려하지 않아도 되기 때문입니다.
+
+### FIFO 페이지 교체 알고리즘
+
+FIFO(first-in-first-out) 페이지 교체 알고리즘은 가장 단순한 방식으로,
+메모리에 가장 먼저 적재된 페이지부터 교체되는 알고리즘입니다.
+프로그램 실행 내내 사용될 페이지 조차 오래되면 교체되기 때문에 페이지 폴트가 빈번하게 일어날 수 있습니다.
+
+> FIFO 페이지 교체 알고리즘의 단점을 보완한 2차 기회 페이지 교체 알고리즘이 있습니다.
+> 페이지의 참조 비트가 1일 경우 참조 비트를 0으로 만든 뒤 현재 시간을 적재 시간으로 변경하고,
+> 메모리에 오래 적재되었더라도 CPU가 최근에 접근한 적이 있다면 교체를 미룹니다.
+
+
+### 최적 페이지 교체 알고리즘
+
+최적 페이지 교체 알고리즘(optimal page replacement algorithm)은 CPU에 의해 참조되는 횟수를 고려하는 페이지 교체 알고리즘입니다.
+사용 빈도가 가장 낮은 페이지를 예측하여 해당 페이지를 교체하는 알고리즘으로 예측하는 것 자체가 까다롭기 때문에 실제 구현이 매우 어렵습니다.
+주로 다른 페이지 교체 알고리즘의 이론상 성능을 평가하기 위한 목적으로 사용하고,
+최적 페이지 교체 알고리즘을 실행했을 때 발생하는 페이지 폴트 횟수를 다른 페이지 교체 알고리즘에서 발생하는 페이지폴트의 하한선으로 간주하여 평가를 합니다.
+
+### LRU 페이지 교체 알고리즘
+
+LRU(least recently used) 페이지 교체 알고리즘은 가장 오랫동안 사용되지 않은 페이지를 교체하는 알고리즘으로,
+페이지마다 마지막으로 사용한 시간을 토대로 가장 사용이 적었던 페이지를 교체합니다.
+
+## 스레싱과 프레임 할당
+
+### 스레싱
+페이지 폴트는 좋지 못한 페이지 교체 알고리즘을 사용하거나,
+프로세스가 사용할 수있는 프레임 자체가 적어서 즉, 메모리 용량이 적으면
+자주 발생하게 됩니다.
+프로세스가 사용할 수 있는 프레임 수가 많으면 일반적으로 페이지 폴트 빈도는 감소합니다.
+이처럼 프로세스가 실제 실행되는 시간보다 페이징에 더 많은 시간을 소요하여 성능이 저하되는 문제를 스래싱(thrashing)이라고 합니다.
+
+
+
+그래프에서 x축은 멀티프로그래밍의 정도를 나타내어 메모리에서 동시 실행되는 프로세스의 수를 의미합니다.
+y축은 CPU 이용률을 나타냅니다.
+이 그래프는 동시에 실행되는 프로세스의 수를 늘린다고 해서 CPU 이용률이 비례해서 증가하는 것이 아님을 보여줍니다.
+아무리 CPU의 성능이 뛰어나도 동시에 실행되는 프로세스를 수용할 물리적 메모리 용량이 적다면 전체 컴퓨터의 성능이 나빠질 수 있습니다.
+
+스레싱이 발생하는 근본적 원인은 각 프로세스가 필요로 하는 프레임 수가 보장되지 않았기 때문입니다.
+예를 들어 $P_1$ 프로세스는 최소 10개의 프레임이 필요한데 5개의 프레임 밖에 없다면,
+페이지 폴트가 자주 발생하게 되고, 스레싱 발생 위험도 증가하게 됩니다.
+그렇기에 운영체제는 각 프로세스들이 무리 없이 실행하기 위한 최소한의 프레임 수를 파악하고,
+프로세스들에게 적절한 수만큼 프레임을 할당해 줄 수 있어야 합니다.
+
+### 프레임 할당
+
+프레임 할당 방식에는 정적 할당 방식과 동적 할당 방식이 있습니다.
+
+#### 정적 할당 방식
+
+정적 할당 방식(static allocation)은 프로세스 의 크기와 물리 메모리의 크기만 고려한 프레임 할당 방식입니다.
+정적 할당 방식에는 균등 할당 방식과 비례 할당 방식이 있습니다.
+균등 할당(equal allocation)은 모든 프로세스들에게 균등하게 프레임을 할당하는 방식으로,
+프로세스들의 크기는 각기 다르더라도 동일한 수의 프레임을 할당하는 방식입니다.
+비례 할당(proportional allocation)은 각 프로세스의 크기에 비례하여 프레임을 할당하는 방식입니다.
+즉, 프로세스의 크기가 크면 더 많은 프레임을 할당하고,
+프로세스의 크기가 작으면 더 적은 프레임을 할당하는 방식입니다.
+
+#### 동적 할당 방식
+
+동적 할당 방식(dynamic allocation)은 각 프로세스의 페이지 부재율에 따라 프레임을 동적으로 할당하는 방식입니다.
+프로세스를 실행하는 과정에서 배분할 프레임을 결정하는 방식에는 작업 집합 모델(working set model)과 페이지 볼트 빈도(PFF:page-fault frequency)가 있습니다.
+작업 집합 모델은 프로세스가 일정 기간 동안 참조한 페이지 집합을 기억하여 빈번한 페이지 교체를 방지하는 방식입니다.
+
+
+
+페이지 폴트 빈도는 페이지 폴트의 빈도수의 상한선과 하한선을 정하여, 상한선이면 프레임을 더 할당하고,
+하한선이라면 프레임을 회수하는 방식입니다.
+
+
\ No newline at end of file