diff --git a/OS/Chaehyun/interview/Interview1.md b/OS/Chaehyun/interview/Interview1.md
new file mode 100644
index 0000000..68661bb
--- /dev/null
+++ b/OS/Chaehyun/interview/Interview1.md
@@ -0,0 +1,72 @@
+### 1. 운영체제에서 메모리 관리가 왜 필요할까?
+
+여러 가지가 존재.
+
+가장 중요한 이유 : 물리 메모리 (RAM)이 비싸고, 용량에 한계가 있다. 감당하지 못하기 때문에, 이것을 관리해야 효율적인 프로세스 관리가 가능. 그리고, 메모리 주소가 바뀌기 때문에, 다른 프로세스들이 메모리를 침범할 수 있다. 떄문에 메모리 관리가 필요!
+
+---
+### 2. 프로세스 메모리 구조에 정리했는데, 코드와 데이터 영역에 대해서 설명해달라
+
+코드와 데이터는 논리적인 단위로 되는데, 구체적인 차이를 설명 못하겠다.
+
+---
+### 3. 코드, 힙, 스택 영역가 존재하는데 왜 스택이 힙보다 더 빠를까?
+
+스택은 고정된 원시 타입들이 들어가 있고, 힙들은 동적으로 할당할 수 있기 때문에, 가변적일 수 있어 그런 부분에서 차이가 있다.
+
+---
+### 4. 캐시에서 가장 중요한 것 → 캐시 적중률! 이것에 관하여 설명
+
+메모리에 접근하면 오래 걸리기 때문에, 캐시를 두어서, 좀 더 빠르게 두어서 하도록 하고 있다!
+캐시 미스가 발생하면, 시간이 오래 걸린다. ex) 페이지 테이블에 캐시를 해 두었는데, 거기에 없으면, 페이지 테이블에 참조를 했다가 다시 메모리에 접근을 해야 되기 때문에 2번 과정 떄문에 더 오래 걸린다.
+
+---
+### 5. 캐시 → 시간 지역성 & 공간 지역성
+
+시간 지역성 : 다시 참조될 수 있는 가능성
+
+공간 지역성 : 주변에 참조될 수 있는 가능성.
+
+시간 지역성 → 반복문, 공간 → 배열이 있다.
+
+---
+### 6. 요구 페이징?
+
+모든 것을 다 메모리에 올리지 않고, 그때 필요한 페이지를 올리고, 그거를 교체를 하는 것을 요구 페이징!
+
+---
+### 7. 페이지 교체 알고리즘 FIFO, LRU 방식이 있는데, 두 가지 알고리즘에 대해서 설명해달라
+
+FIFO : 처음에 들어간 페이지를 무조건 내보낸다! → 비효율적
+
+LRU : 지역성을 고려하여서, 적게 사용한 페이지를 내보내서, 좀 더 효율적으로 할 수 있게 하도록 한다.
+
+---
+### 8. 스와핑이란?
+
+디스크에 잠깐 적재를 할 수 있는 공간 → 메모리에 넣으면 비효율적. 스왑아웃으로 디스크에 넣어주고, 다시 스왑인해서 가져와준다.
+
+---
+### 9. 스와핑이 반복되었을 때의 문제점?
+
+자주 사용되는 페이지를 거기에 올려버리면, 접근하는 시간이 오래 걸린다.
+
+---
+
+### 10. 내부 단편화에 대해서 설명해달라
+
+프로세스가 정해진 공간보다 작아서 내부에서 생기는 공간 → 내부 단편화!
+
+페이지는 고정적인 공간에 들어가지만, segmentation 기법에서는 모르겠습니다 죄송합니다!
+
+---
+
+## Feedback
+### From 소미
+전체적인 태도나 대답 내용이 다 좋았던 것 같습니다. 자신있는 부분이 나올 때 말하는 속도가 갑자기 빨라지는 면이 있어서 이 부분만 보완하면 체고일 것 같습니다.
+
+### From 나연
+발성이 좋았다! 발성이 매우 신뢰가 좋아 보인다. 질문자 눈을 똑바로 쳐다보면서 하면 더 좋을 것 같다!
+
+### From 수정
+전반적으로 밝게 답변하는 점이 인상적이었고, 단순한 질문보다는 오히려 깊이 있는 질문에서 더 많은 답변을 풀어낼 수 있을 것 같다는 느낌을 받았습니다. 웃으며 대답하는 모습이 좋았습니다.
diff --git a/OS/Nayoun/Deadlock.md b/OS/Nayoun/Deadlock.md
new file mode 100644
index 0000000..9ea12c8
--- /dev/null
+++ b/OS/Nayoun/Deadlock.md
@@ -0,0 +1,357 @@
+# 프로세스 동기화
+
+## 동기화
+
+> 특정 자원에 접근할 때 한 개의 프로세스만 접근하게 하거나 프로세스를 올바른 순서대로 실행하게 하는 것
+>
+
+프로세스 동기화 : 프로세스들 사이의 수행 시기를 맞추는 것 !!
+
+동기화는 목적에 따라 다음과 같이 구분할 수 있다.
+
+1. 실행 순서 제어를 위한 동기화
+ 1. 동시에 실행되는 프로세스를 올바른 순서대로 실행하게 하기!
+2. 상호 배제를 위한 동기화
+ 1. 공유가 불가능한 자원의 동시 사용을 피하기 위해!
+ 1. 한 자원에 대해 두 프로세스가 접근하면 → 최종 결과에 영향을 줄 수도 있다.
+
+## 생산자와 소비자 문제
+
+**related to** 상호 배제를 위한 동기화
+
+
+
+## 공유 자원과 임계 구역
+
+- 공유 자원
+ - 공동으로 이용하는 변수, 파일, 장치 등
+- 임계 구역
+ - 공유 자원에 접근하려는 코드 중 동시에 실행하면 문제가 발생하는 코드 영역
+
+> 2개 이상의 프로세스가 임계 구역에 진입하고자 할 때, 둘 중 하나는 대기가 필요하다!
+
+먼저 진입한 프로세스 작업이 마무리 되어야, 대기 프로세스가 임계 구역에 진입할 수 있다.
+>
+
+- race condition
+ - 잘못된 실행으로 인해 여러 프로세스가 동시 다발적으로 임계 구역의 코드 실행하면 문제가 될 수 있다!
+ - 이것이 발생하면 데이터의 일관성이 깨지는 문제가 발생!!
+ - 컴퓨터) 저급 언어 실행(고급 언어 X) => 여러 줄의 저급 언어로 변환된 고급 언어 한 줄 실행하는 과정에서 문맥 교환
+
+### 상호 배제를 위한 동기화 3가지 원칙
+
+1. 상호 배제
+ 1. 한 프로세스가 임계 구역에 진입했다면 → 다른 프로세스가 임계 구역에 들어올 수 없다!
+2. 진행
+ 1. 임계 구역에 어떤 프로세스도 진입하지 않았다면, 임계 구역에 진입하고자 하는 프로세스는 들어갈 수 있어야 한다!
+3. 유한 대기
+ 1. 한 프로세스가 임계 구역에 진입하고 싶다면, 그 프로세스는 무한히 대기하지 않고, 언젠가는 임계 구역에 들어올 수 있어야 한다!
+
+## 동기화 기법
+
+> 동기화를 위한 대표적인 방법이 뭐가 있을까?
+>
+
+### mutex lock
+
+> 동시에 접근해서는 안되는 자원에 동시에 접근하지 않도록 만드는 도구
+>
+- 어떻게?
+ - 임계 구역을 잠금으로써, 프로세스 간 상호 배제를 한다!
+- 형태
+ - 자물쇠 역할 (프로세스들이 공유하는 전역 변수 `lock`)
+ - `acquire` 함수 : 임계 구역을 잠근다!
+ - 프로세스가 임계 구역에 진입하기 전에 호출한다.
+ - 임계 구역이 잠겨 있으면,
+ - 열릴 때까지 (`lock → false`) 임계 구역을 반복적으로 확인
+ - 임계 구역이 열려 있으면,
+ - 임계 구역을 잠근다. (`lock → true`)
+ - `busy wait` : 반복적으로 임계 구역이 잠겨 있는지 확인한다!
+
+ > 락을 획득하지 않으면, 무작정 대기하게 하고, 락을 획득하면 임계 구역을 잠근 뒤 임계 구역에서 작업하게 한다!
+ >
+
+ ```tsx
+ acquire() { // 임계 구역이 잠겨 있는지 반복적 확인
+ while (lock == true)
+ ;
+ lock = true;
+ }
+
+ release() {
+ lock = false;
+ }
+
+ // 하나의 프로세스만 임계 구역에서 작업
+ acquire(); // 자물쇠 잠겨 있는지 확인, 잠김 X -> 잠그고 들어가기
+ // 임계 구역 // 작업 진행
+ release(); // 자물쇠 반환
+
+ // 생산자 소비자 문제
+ acquire();
+ // '총합' 변수 접근
+ release();
+ ```
+
+ - `release` 함수 : 임계 구역의 잠금을 해제한다!
+ - 프로세스가 임계 구역에서의 작업이 끝나고 호출한다.
+ - 현재 잠긴 임계 구역을 열어준다. (`lock → false`)
+
+### semaphore
+
+> mutex lock보다 조금 더 일반화된 방식의 동기화 도구, 공유 자원이 여러 개 있는 상황에서도 적용 가능한 동기화 도구이다!
+>
+1. `전역 변수` : 임계 구역에 진입할 수 있는 프로세스의 개수 ( = 사용 가능한 공유 자원의 개수)
+2. `wait 함수` : 임계 구역에 들어가도 좋은지, 기다려야 할지 알려준다.
+3. `signal 함수` : 임계 구역 앞에서 기다리는 프로세스에 ‘이제 가도 좋다’ 라는 신호를 준다.
+
+```tsx
+wait() {
+ while (S <= 0) // 임계 구역에 진입할 수 있는 프로세스 개수 <= 0
+ ; // 사용할 수 있는 자원이 있는지 반복적으로 확인
+ S--; // 임계 구역에 진입할 수 있는 프로세스 개수 1개 이상 -> S 1감소, 임계 구역 진입
+}
+
+signal() {
+ S++: // S 1증가
+}
+
+// 임계 구역 전후로(= 뮤텍스 락)
+wait()
+// 임계 구역
+signal()
+```
+
+
+
+> 프로세스 P1, P2, P3가 2개의 공유 자원에 P1, P2, P3 순서대로 접근
+>
+>
+> 공유 자원 2개 -> 변수 S : 2
+>
+
+1. P1 : `wait` 호출 / S: 현재 2 → 1 감소, 임계 구역 진입
+
+2. P2 : `wait` 호출 / S: 현재 1 → 0 감소, 임계 구역 진입
+
+3. P3 : `wait` 호출/ S: 현재 0 → **무한히 반복하며 S 확인**
+
+4. P1 : 임계 구역 작업 종료, `signal()` 호출/ S: 1 증가
+
+5. P3 : S가 1 됨 확인 / S: 현재 1 → 1 감소, 임계 구역 진입
+
+하지만 여기서의 **Problem** : 사용할 수 있는 공유 자원이 없을 때 (위에서는 P3), 프로세스는 무한히 반복하며 S를 확인해야 한다!
+
+**Sol** : 대기 queue 개념 도입!
+
+```tsx
+wait() {
+ S--;
+ if (S < 0) {
+ add this process to Qeueu; // 해당 프로세스 PCB -> 대기 큐에 삽입
+ sleep(); // 대기 상태
+ }
+}
+
+signal() {
+ S++;
+ if (S <= 0) {
+ remove a process p from Queue; // 대기 큐에 있는 프로세스 p 제거
+ wakeup(p); // 프로세스 p를 대기 상태 -> 준비 상태
+ }
+}
+```
+
+1. P1 : wait 호출 / S: 1 감소 -> S는 1 => 임계 구역 진입
+
+2. P2 : wait 호출 / S: 1 감소 -> S는 0 => 임계 구역 진입
+
+3. P3 : wait 호출/ S: 1 감소 -> S는 -1 => 본인의 PCB를 대기 큐에 넣고 대기 상태로 전환
+
+4. P1 : 임계 구역 작업 종료 → signal() 호출 → S(= -1)가 1 증가되어 → 0 → 대기 상태였던 P3를 대기 큐에서 꺼내 준비 큐로 옮겨줌
+
+5. 깨어난 P3 : 임계 구역 진입
+
+6. P2 : 임계 구역 작업 종료 → signal() 호출 → S(= 0)가 1 증가되어 → 1
+
+7. P3 : 임계 구역 작업 종료 → signal() 호출 → S(= 1)가 1 증가되어 → 2
+
+실행 순서 제어용 `semaphore` 패턴:
+
+
+
+세마포의 변수 S를 0으로 두고 먼저 실행할 프로세스 뒤에 `signal`, 다음에 실행할 프로세스 앞에 wait
+
+### monitor
+
+> semaphore에 비해 사용자가 사용하기 편리한 동기화 도구
+>
+- 왜 편리? : (공유 자원 + 공유 자원에 접근하기 위한 인터페이스 = 통로)를 묶어서 관리!
+- 프로세스가 `interface`을 통해서만 공유 자원에 접근하도록!
+- `monitor`는 공유 자원에 접근하고자 하는 프로세스를 큐에 삽입하여, 순서대로 하나씩 공유 자원 이용
+- 상호 배제를 위한 동기화 제공
+ - = 공유 자원을 다루는 인터페이스에 접근하기 위한 큐(모니터에 진입하기 위한 큐)를 만들고, **모니터 안에 항상 하나의 프로세스만 들어오도록**
+- 실행 순서 제어를 위한 동기화 제공
+ - 특정 조건 바탕으로 프로세스를 실행하고 일시 중단 → **조건 변수(condition variable)** 사용!
+
+ *조건 변수: 프로세스나 스레드의 실행 순서를 제어하기 위해 사용하는 특별한 변수, 자체는 값을 안 가지고 `wait`, `signal` 함수를 호출해 실행 순서를 제어하기 위해 사용됨!*
+
+
+
+
+# Deadlock
+
+## dining philosopher problem
+
+`deadlock`의 대표적인 예시!
+
+- 철학자 = `Process or thread`
+- 포크 = 자원 (=임계구역)
+- 어떤 포크를 집을까 생각하는 행위 = 자원을 기다리는 것.
+
+> 즉, 상대방이 가진 자원을 기다리기만 하다가, 결국 실행을 못하는 상황을 말하는 것이다.
+>
+
+## resource-allocation graph
+
+> 어떤 프로세스가 어떤 자원을 사용하고 있고, 어떤 자원을 기다리고 있는지를 표현하는 간단한 그래프
+>
+- 교착 상태를 표현할 수 있다!
+1. 프로세스 - 원 / 자원의 종류 - 사각형
+2. 사용할 수 있는 자원의 개수 - 자원 사각형 내에 점으로 표현
+3. 프로세스가 어떤 자원을 할당받아 사용 중: 자원 → 프로세스(화살표 표시)
+4. 프로세스가 어떤 자원 기다리고 있음: 프로세스 → 자원(화살표 표시)
+
+`deadlock`이 발생하면 이 그래프가 원의 형태를 띄고 있다!
+
+## 교착 상태 발생 조건
+
+- **상호 배제(mutual exclusion)**
+ - 한 프로세스가 사용하는 자원을 다른 프로세스가 사용할 수 없을 때
+- **점유와 대기(hold and wait)**
+ - 자원을 할당받은 상태에서 다른 자원을 할당받기를 기다리는 상태
+- **비선점(nonpreemptive)**
+ - 자원을 이용하는 프로세스의 작업이 끝나야만 이용할 수 있음= 어떤 프로세스도 다른 프로세스의 자원 강제로 빼앗지 못함
+- **원형 대기(circular wait)**
+ - 프로세스들이 원의 형태로 자원을 대기*원의 형태를 띈다고 해서 반드시 교착 상태 발생하는 것 X*
+
+## 교착 상태 해결 방법
+
+### 교착 상태 예방
+
+> 교착 상태 발생 조건 4가지 중 하나를 충족하지 못하게 하는 방법!
+>
+1. **상호 배제 없애기**
+ 1. 모든 자원을 공유 가능하게 만든다.
+ 2. ***하지만, 이것은 현실적으로 모든 자원의 상호 배제를 없앨 수 없다.***
+2. **점유 대기 없애기**
+ 1. 프로세스가 필요한 모든 자원을 한 번에 요청!
+ 1. 즉, 전부 못 받는 상황이면, 아무것도 안 받는 것.
+ 2. 하지만 이것은, 당장 자원이 필요해도 대기해야 하고, 사용되지 않으면서 오랫동안 할당되는 자원을 다수 양산하므로, 자원의 활용률이 낮아진다.
+ 3. 그리고, 자원을 많이 사용하는 프로세스는 자원을 사용할 타이밍을 확보하기 어렵다.
+ 1. ⇒ **기아 현상** 발생!
+3. **비선점 조건 없애기**
+ 1. 자원을 이용 중인 프로세스로부터 해당 자원을 뺏을 수 있다!
+ 1. 즉, 작업이 끝나지 않아도 다른 프로세스의 CPU를 할당받아 사용할 수 있다.
+ 2. 하지만, 모든 자원이 선점이 가능한 것은 아니다!
+4. **원형 대기 조건 없애기**
+ 1. 모든 자원에 번호를 부여해서, 오름차순으로만 자원을 요청하도록 한다.
+ 1. 이러면, 대기 관계에 사이클이 생성이 불가!
+ 2. but, 자원 번호 설계가 어렵고, 자원 활용률이 저하된다.
+
+### 교착 상태 회피
+
+> 교착 상태가 발생할 가능성이 있는 상황을 피해 가며 자원을 할당하기
+>
+
+즉, 프로세스들에 배분할 수 있는 자원의 양을 고려하여, 교착 상태가 발생하지 않을 정도의 양만큼만 자원을 배분하기!
+
+- Safe State
+ - **모든 프로세스가 정상적으로 자원을 할당받고 종료할 수 있는 상태**
+ - 즉, 안전 순서열이 있는 상태!
+- Unsafe State
+ - **교착 상태가 발생할 수도 있는 상황**
+ - 안전 순서열이 없는 것.
+- Safe Sequence
+ - **프로세스들을 어떤 순서로 실행하면 교착 상태 없이 모두 종료할 수 있는지 나타낸 순서**
+
+- **Example**
+
+
+
+
+- 할당 가능한 자원이 12라고 할때,
+ - 첫번째 예제에서 할당한 자원은 → 10개. 남은 자원은 12 - 10 = 2이다.
+ - 하지만 이것은 불안전 상태가 존재!
+ - ex) P1, P2, P3가 모두 최대로 자원을 요구할 때,
+ - 할당 가능한 자원 = 12
+ - 할당한 자원 = 10 + 2 = 12
+ - 남은 자원 = 12 - 12 = 0
+ - 여기서, P2가 작업을 끝내고, 반환하면,
+ - 할당 가능한 자원은 12 - 4 = 8.
+ - 남은 자원은 4가 된다.
+ - 하지만, 여기서, P1과 P3의 요구를 들어줄 수 없다!
+ - 따라서, P1과 P3가 모두 자원을 무한정으로 기다리므로, 교착 상태가 발생!
+
+### 교착 상태 검출 후 회복
+
+> 교착 상태가 발생하는 것을 허용하고, 발생했음을 ‘검출’한 뒤 ‘사후 조치’로 해결하는 방식
+>
+- 프로세스들이 자원을 요구할 때마다 모두 할당하고, 교착 상태 발생 여부를 주기적으로 검사한다.
+- 교착 상태 검출은? 자원 할당 그래프를 통해서 한다.
+ - 사이클이 발견되면 → 교착 상태인 것!
+- 교착 상태 회복은?
+ 1. 선점! ⇒ 하지만, 모든 자원이 선점 가능하지 않으므로, 구현이 어렵다.
+ 1. 교착 상태에 포함된 프로세스 집합 선택
+ 2. 그 중 하나를 희생자(victim)로 선정
+ 3. 자원 강제 회수
+ 4. 다른 프로세스에 할당
+ 5. 교착 상태 해소될 때까지 반복
+ 2. 프로세스 강제 종료 ⇒
+ 1. 모든 프로세스 강제 종료
+ 1. 교착 상태에 포함된 모든 프로세스를 종료
+ 1. but 모든 작업 내역이 손실될 수 있다.
+ 2. 한 프로세스씩 강제 종료
+ 1. 교착 상태가 풀릴 때까지 하나씩 종료.
+ 1. 피해를 최소화하지만, 비용이 발생한다.
+- 타조 알고리즘
+ - → 교착 상태는 드물다라고 가정하고, 아예 무시하는 것!
diff --git a/OS/Nayoun/Memory.md b/OS/Nayoun/Memory.md
new file mode 100644
index 0000000..3328a2f
--- /dev/null
+++ b/OS/Nayoun/Memory.md
@@ -0,0 +1,429 @@
+# **메모리 관리 (Main Memory Management)**
+
+> 메모리는 실행 중인 프로세스가 **명령어와 데이터를 저장하고 접근하는 핵심 자원**
+>
+
+> 운영체제는 이 메모리를 **안전하고 효율적으로 관리한다!**
+>
+
+## **메모리 관리의 배경**
+
+### **프로세스와 메모리의 관계**
+
+- **프로세스**란 실행 중인 프로그램을 의미하며, 반드시 **메인 메모리(Main Memory)** 에 적재되어야 실행 가능하다.
+
+프로그램이 시작되면 → 독자적인 주소 공간이 형성됨.
+
+프로그램이 실행되려면 물리적인 메모리 어딘가로 올라가야 하고, 이러면 주소가 바뀌게 된다.
+
+따라서 프로그램이 물리적인 메모리에 어디로 올라갈지 주소로 결정하는 것을 주소 바인딩이라고 한다!
+
+## **주소 개념과 메모리 할당 과정 (Address Binding)**
+
+### 1. Symbolic Address
+
+변수명, 함수명, 라벨 처럼 개발자 편의성을 위한 주소이다.
+
+ex) `sum, x, goto L1` 과 같은 변수명, 함수명, 라벨
+
+### 2. Logical Address (Virtual Address)
+
+각 프로세스가 독립적으로 갖는 CPU 주소이다. → 즉, CPU가 보는 주소!
+
+ex) `346, x01000`처럼 프로세스 기준으로 보는 주소
+
+### 3. Physical Address
+
+메인 메모리(RAM)에 실제로 적재된 위치이다.
+
+## **Address Binding이란?**
+
+코드가 컴파일 되면 독자적인 숫자 주소가 만들어지고, 실행 되려면 물리적 메모리에 올라가야 하기 때문에 symbolic address → physical address로의 주소 변환이 필요하다.
+
+그리고 주소가 변환되는 시점에는 크게 3가지가 있다.
+
+### Compile Time Binding
+
+- 컴파일 할 때 이미 물리적 주소가 결정된다.
+- 이렇게 미리 결정이 되어야 하기 때문에 Logical Memory 그대로 물리적 메모리 주소로 올려야 한다. → 이러면 굉장히 비효율적! 왜냐? 물리적 메모리에 주소가 많이 비었는데도 불구하고, 항상 0번지부터 Logical Address에 올려야 하기 때문에.
+
+### Load Time Binding
+
+- 컴파일 떄에는 논리적인 주소만 결정이 되고, 메모리에 올라갈 떄 물리적 주소가 결정됨!
+
+### Execution Time Binding (Run Time)
+
+- 프로그램이 시작할 때 주소가 결정되는 부분은 똑같으나, 실행 도중에 물리적 주소가 바뀔 수 있다!
+- ⇒ 이게 현재 시스템에 사용되는 방식이다. 하지만 Run Time Binding 방식은 CPU가 메모리 주소를 요청할 떄마다 Binding을 체크해 주소 변환을 그때그때 해줘야 하므로 하드웨어 (MMU)가 필요하다!
+
+## **MMU (Memory Management Unit)**
+
+> 논리적 주소 → 물리적 주소 변환을 담당하는 **하드웨어 장치**
+>
+
+### **MMU의 역할**
+
+- CPU가 생성한 **논리 주소**를 **물리 주소로 변환**하여 메모리에 접근하도록 한다.
+
+### **MMU의 구성 요소**
+
+
+
+
+- **Relocation Register =** MMU에서의 Base Register (=메모리에 프로그램이 할당될 때 프로그램의 시작 register 주소) !
+ - 논리 주소 + 재배치 값 = 물리 주소
+
+For example, 논리 주소가 346, 재배치 레지스터가 14000이면 물리 주소 **14346이다!**
+
+## **동적 로딩 (Dynamic Loading)**
+
+**로딩** : 메모리에 데이터를 옮기는 것.
+
+프로그램 전체를 **한 번에 메모리에 올릴 필요는 없다! 따라서, 동적 로딩을 사용해 필**요한 **루틴(함수)** 만 메모리에 적재해서, 실제 호출 시점에 로딩하도록 하면 더 효율적이게 된다.
+
+⇒ 하지만 이거는 메모리가 부족했을 때 사용되는 방법이였고, 가상 메모리가 나오고 나서는 더 필요한 경우가 없어짐!
+
+# 연속 메모리 할당
+
+> 서로 다른 프로세스에 연속적인 메모리 공간을 할당하는 방식.
+
+각각의 프로세스는 다음 프로세스를 포함하는 영역까지의 연속적인 메모리의 단일 영역을 포함하고 있다.
+
+## 메모리 할당
+
+> 메모리 내에 빈 공간이 여러 개 있다면, 프로세스를 어디에 배치해야 하나?
+
+### First Fit
+
+OS가 메모리 내의 빈 공간을 순서대로 검색하다가 → 적재할 수 있는 공간을 발견하면 그 공간에 프로세스를 배치한다!
+
+프로세스가 적재될 수 있는 공간을 발견하는 즉시 메모리를 할당 → 검색 최소화 & 빠른 할당 가능
+
+### Best Fit
+
+OS가 빈 공간을 모두 검색해 본 후 , 적재될 수 있는 공간 중 가장 작은 공간에 프로세스를 배치한다.
+
+### Worst Fit
+
+OS가 빈 공간을 모두 검색해 본 후, 프로세스가 적재될 수 있는 공간 중 가장 큰 공간에 프로세스를 배치한다.
+
+
+
+위와 같은 메모리 공간이 있다고 가정할때 200MB, 15MB, 185MB, 75MB, 175MB, 80MB가 순서대로 요청할때 **First-Fit, Best-Fit, Worst-Fit**으로 할당한 결과는 다음과 같다.
+
+
+
+
+## 외부 단편화
+
+> 연속 메모리의 할당의 문제점
+>
+
+→ 연속 메모리 할당을 하면, 프로세스를 할당하기 어려울 만큼 작은 메모리 공간들로 인해 메모리가 낭비된다!
+
+
+
+즉, 위와 같은 사용자 영역에서(프로세스가 적재된 공간), 총 비어있는 메모리 공간은 100MB이나, 프로세스 C를 담을 만큼 연속적인 공간이 생기지 않아, 할당할 수 없고, 결론적으로 남아있는 메모리 공간이 낭비되게 된다!
+
+**그러면 이게 왜 문제가 되냐?**
+
+연속 메모리 할당 환경에서는, 프로세스들이 실행되고 종료되는 과정이 반복되며 메모리 사이사이에 빈 공간들이 생긴다. 이런식으로 빈 공간들이 계속 생기면 → 그 공간보다 큰 프로세스를 적재하기 어려운 상황이 초래된다.
+
+**그러면 해결 방법은?**
+
+**Compaction!** → 여기저기 흩어져 있는 빈 공간들을 하나로 모은다.
+
+하지만 이 방식에는 다음과 같은 문제점이 있다.
+
+1. 압축하는 동안 시스템은 하던 일을 모두 중지해야 한다.
+2. 메모리에 있던 내용을 옮기는 일은 많은 오버헤드를 야기한다.
+3. 어떤 프로세스를 어떻게 움직여야 오버헤드를 최소화하며 압축할 수 있는지 명확한 방법이 없다.
+
+**그러면 또 다른 해결 방법은? → 페이징!**
+
+## 내부 단편화
+
+페이징에서, 프로세스가 페이지 단위로 쪼개지지 않아, 남은 프로세스가 낭비되는 현상
+
+
+
+
+따라서 OS는 내부 단편화를 적당히 방지하며, 너무 크지 않은 페이지 테이블이 만들어지지 않도록 하는 페이지 크기를 자동으로 계산한다.
+
+## 스와핑
+
+> **Prob :** 메모리에 적재된 프로세스 중에는 현재 실행되지 않는 프로세스가 있을 수 있다. (ex) 대기 상태 or 오랫동안 사용되지 않은 프로세스)
+>
+
+**Sol :** 따라서 이런 프로세스를 임시 **보조기억장치**로 쫓아내고, 그렇게 해서 **생긴 메모리상의 빈 공간에 또 다른 프로세스를 적재**하여 실행하는 방식으로 해결한다!
+
+
+
+
+**Swap Space** : 오른쪽에, 프로세스들이 쫓겨나는 보조기억장치의 일부 영역
+
+**Swap Out** : 현재 실행되지 않은 프로세스가 메모리에서 swap 영역 (=backing store)로 옮겨지는 것
+
+**Swap In** : Swap 영역에 있던 프로세스가 다시 메모리로 옮겨져 오는 것.
+
+**Swap Out** 되었던 프로세스가 다시 **Swap In** 되었을 때는 전의 물리 주소와는 다른 주소에 적재될 수 있다!
+
+이러한 스와핑을 이용하면, 프로세스들이 요구하는 메모리 주소 공간의 크기가 실제 메모리 크기보다 큰 경우에도 프로세스들을 동시에 실행할 수 있다!
+
+
+
+# Paging
+
+메모리에 페이지를 연속적으로 할당하면 → 메모리보다 큰 프로그램을 적재할 수 없다.
+
+따라서 **Virtual Memory**라는 기술을 사용해, 실행하고자 하는 프로그램 일부만 메모리에 적재해, 실제 물리 메모리 크기보다 더 큰 프로세스를 실행할 수 있게 한다.
+
+가상 메모리 기법에는 **Paging, Segmentation**이 있지만, 오늘날 **대부분의 OS는 페이징을 사용**한다.
+
+> **프로세스의 논리 주소 공간을 Page라는 일정한 단위**로 자르고, **메모리 물리 주소 공간을 Frame**이라는 크기로 자른뒤, 페이지를 프레임에 할당하는 관리 기법
+>
+
+페이징에도 **SwapOut / SwapIn 개념이 사용**된다!
+
+즉, 메모리에 적재될 필요가 필요없는 페이지는 보조기억장치로 Page Out 되고, 필요한 페이지들은 Page In이 된다.
+
+## Page Table
+
+하지만, 프로세스가 메모리에 불연속적으로 배치되어 있다면
+→ **CPU는 프로세스를 이루는 페이지가 어느 프레임에 적재되어 있는지 알기 어렵기 때문**에
+→ **실행하기 어려워 진다.**
+
+
+
+
+이를 해결하기 위해, **물리 주소 (실제 메모리 내 주소)에 불연속적으로 배치**되더라도,
+**논리 주소 (CPU가 바라보는 주소)에는 연속적으로 배치**되도록 페이지 테이블을 사용한다!
+
+즉, CPU는 페이지 테이블을 통해 페이지 번호만 보고 해당 페이지가 어떤 프레임에 할당되었는지 알려준다.
+
+### PTBR : Page Table Base Register
+
+각 프로세스의 페이지 테이블이 적재된 주소를 가리킨다.
+
+
+
+
+**Prob :** 그런데 이런 구조를 사용하면, 메모리 접근 시간이 두 배로 늘어난다
+
+→ 페이지 테이블 접근, 그리고 프레임 접근하기 위해.
+
+### Sol : TLB : Translation Lookaside Buffer
+
+CPU 옆에 두어지는 캐시 메모리.
+
+캐시이기 때문에, 페이지 테이블의 일부 내용을 저장할 수 있고, 참조 지역성에 근거해 주로 최근에 사용된 페이지를 위주로 가져와 저장한다.
+
+
+
+
+**TLB Hit :** CPU가 발생한 논리 주소에 대한 페이지 번호가 TLB에 있다.
+
+**TLB Miss :** TLB에 없어서 메모리 내의 페이지 테이블을 접근할 때 !
+
+## 페이징에서의 주소 변환
+
+메모리의 특정 주소에 접근하려면 다음과 같은 정보가 필요하다.
+
+1. 어떤 `page` or `frame`?
+2. 접근하려는 주소가 page or frame으로부터 얼마나 떨어져 있는지?
+
+때문에 **페이징 시스템에서는 모든 논리 주소가 `page number & offset` 으로 이루어져 있다!**
+
+CPU가 32bit address를 내보냈다면, 그 중 `N비트`는 `page number`, `32-N 비트`는 `offset`.
+
+`page number` → 접근하고자 하는 페이지 번호 (페이지가 어떤 프레임에 할당되었는지?)
+
+`offset` → 접근하려는 주소가 frame의 시작 번지로부터 얼만큼 떨어져있는지?
+
+즉, ` → ` 으로 변환된다.
+
+## PTE : Page Table Entry
+
+
+
+
+- `Valid bit`
+ - **현재 해당 페이지에 접근 가능한지 여부 알려줌**
+ - 메모리에 적재되어 있지 않다면 0, 적재되어 있다면 1
+ - 현재 페이지가 메모리에 적재돼 있는지 여부 알려주는 비트이므로 페이지가 메모리 내에 없다면 아래와 같은 `Exception`(=`Page Fault`)이 발생한다!
+- `Protection Bit`
+ - **페이지에 접근할 권한을 제한하여 페이지를 보호하는 기능을 제공**해준다.
+ - 해당 페이지가 읽기/쓰기 모두 가능한 페이지인지, 읽기만 가능한 페이지인지 나타냄
+ - 읽기만: `0`/ 읽기와 쓰기: `1`
+ - 읽기 `r(Read)`/ 쓰기 `w(Write)`/ 실행 `x(eXecute)`
+ - ex) 보호 비트 `100: r 1/ w 0/ x 0` => 읽기만 가능
+- `Reference Bit`
+ - **CPU가 이 페이지에 접근한 적 있는지 여부** 알려줌
+ - 적재 이후 한 번도 읽거나 쓴 적 없었다면, 페이지는 0으로 유지, CPU가 읽거나 쓴 페이지면 1
+- `Modified bit` = `Dirty bit`
+ - **해당 페이지에 데이터를 쓴 적 있는지 없는지 수정 여부** 알려줌
+ - 한번도 접근한 적 없거나, 읽기만 했던 페이지면 0, 변경된 적 있는 페이지면 1
+ - 그럼 왜 존재할까?
+ - → **페이지가 메모리에서 사라질 때 보조기억장치에 쓰기 작업을 해야 하는지, 할 필요 없는지 판단**해준다!
+ - 읽기만 한 페이지면 CPU는 다음과 같이 판단한다.
+ - 보조기억장치에 저장된 해당 페이지의 내용 == 메모리에 저장된 페이지의 내용
+ - => 한 번도 수정된 적 X 페이지가 스왑 아웃 -> 새로 적재된 페이지로 덮어쓰면 됨
+ - 하지만, 쓰기 작업한 페이지면, CPU는 다음과 같이 판단한다.
+ - 보조기억장치에 저장된 해당 페이지의 내용 != 메모리에 저장된 페이지의 내용
+ - => 변경된 값을 보조기억장치에 기록하는 작업 추가
+
+# 페이지 교체 알고리즘
+
+
+
+## Demand Paging
+
+> 프로세스를 메모리에 적재할때, **필요한 페이지만을 메모리에 적재**하는 기법
+이를 수행하기 위해서는 **1. 페이지 교체 , 2. 프레임 할당** 문제를 반드시 해결해야 한다.
+>
+
+### 절차
+
+1. CPU가 특정 페이지에 접근하는 명령어 실행
+2. `Valid Bit == 1` (=해당 페이지가 현재 메모리에 있으면), CPU는 페이지가 적재된 프레임에 접근
+3. `Valid Bit == 0`, `Page Fault` 발생
+ 1. `Page Fault Routine` 실행 → 해당 페이지를 메모리로 적재하고, `Valid Bit = 1`로 설정
+ 2. 다시 1번 수행
+
+
+## Page Replacement Algorithm
+
+> `demand paging`으로 페이지를 적재하다 보면 → 언젠가 메모리가 가득차게 된다.
+그러면 메모리에 적재된 페이지를 보조기억장치로 내보내야 되는데, **내보내는 페이지를 결정하는 기법 = 페이지 교체 알고리즘**이라 한다!
+>
+
+일반적으로 `Page Fault`를 가장 적게 일으키는 알고리즘을 가장 좋은 알고리즘으로 평가한다.
+
+왜냐? → `Page Fault`가 많이 발생하면 = 보조기억장치로 내쫓을 페이지를 잘못 골랐다 = 컴퓨터의 성능을 저해하기 때문!
+
+
+
+우리는 다음과 예제를 사용해서 알고리즘을 공부해도록 한다.
+
+
+
+### First-in First-out
+
+
+
+
+
+
+이 알고리즘은 15 번의 `Page Fault`을 발생시켰다.
+
+아이디어와 구현은 간단하지만, 프로그램 실행 초기에 적재된 페이지 중 실행 내내 사용될 내용을 포함하고 있는 페이지를 내쫓을 수 있으므로, 효율이 안좋을 수 있다.
+
+### Optimal Page Replacement Algorithm
+
+
+
+즉, 사용 빈도가 가장 낮 페이지를 교체한다.
+
+
+
+
+4번째 과정에서 2번 페이지를 넣고자 할 때, 7번 페이지가 가장 안 쓰이기 때문에, 7번 페이지와 교체한다.
+
+이 알고리즘은 9 번의 `Page Fault`을 발생시킨다.
+
+하지만 앞으로 오랫동안 사용되지 않을 페이지 예측이 어려우므로, 성능 평가 목적으로만 사용된다.
+
+### Least Recently Used Page Replacement Algorithm
+
+
+
+
+
+
+- 4번째 과정에서 2번 페이지를 넣고자 할때 7번 페이지가 가장 오랫동안 사용되지 않았으므로 7번 페이지를 페이지 아웃시키고 2번 페이지를 넣는다.
+- 6번째 과정에서 3번 페이지를 넣고자 할때 1번 페이지가 가장 오랫동안 사용되지 않았으므로 1번 페이지와 교환한다.
+- 페이지 폴트 발생 횟수 : `12회`
+
+## Thrashing
+
+
+
+왜냐? → 프레임이 무한히 많은 컴퓨터와 프레임이 한 개만 있는 컴퓨터를 비교해보면, 전자는 페이지를 수용할 공간이 넉넉해 모든 프로세스의 페이지가 메모리에 적재될 수 있지만, 후자는 새로운 페이지를 참조할 때 마다 Page Fault가 발생한다.
+
+이렇게, **프로세스가 실제 실행되는 시간보다 페이징에 더 많은 시간을 소요하여 성능이 저해되는 문제** = `Thrashing`이라고 한다!
+
+
+
+
+`x축` : 메모리에 올라와 동시에 실행 중인 프로세스 개수.
+
+`y축` : CPU가 실제로 일을 하고 있는 비율
+
+프로세스 수가 증가하면 CPU 이용률이 점차 증가하는 양상을 보이지만, `thrashing` 구간에서는 프로세스가 너무 많아져, 각 프로세스가 필요한 페이지를 메모리에 유지하지 못하는 문제가 발생해 CPU 이용률이 급락하게 된다.
+
+Thrashing이 발생하는 원인은, **각 프로세스가 필요로 하는 최소한의 프레임 수가 보장**되지 않았기 때문이다.
+따라서 OS는** 각 프로세스들이 무리 없이 실행하기 위한 최소한의 프레임 수를 파악**하고 **프로세스들에 적절한 수만큼 프레임을 할당**해 줄 수 있어야 한다.
+
+**프레임의 할당 방식 - 1. 정적 할당 방식**
+
+단순히 프로세스의 물리 메모리 크기만 고려한다!
+
+1. `Equal Allocation`
+ 1. 모든 프로세스들에게 동등하게 프레임들을 똑같이 할당함
+2. `Proportional Allocation`
+ 1. 프로세스의 크기에 따라서 프레임을 차등 할당함
+
+**프레임의 할당 방식 - 1. 동적 할당 방식**
+
+프로세스를 실행해보고, 할당할 프레임 수를 결정한다.
+
+1. `Working Set Model`
+ 1. Working Set 크기 만큼한 프레임을 할당한다.
+ 2. 즉, 프로세스가 일정 기간 동안 참조한 페이지 집합을 기억해, 빈번한 페이지 교체를 방지한다
+2. `Page-Fault Frequency`
+ 1. Page Fault 율에 상한선과 하한선을 정하고, 그 내부 범위 안에서만 프레임을 할당한다.
diff --git a/OS/Nayoun/Process.md b/OS/Nayoun/Process.md
new file mode 100644
index 0000000..16da2ce
--- /dev/null
+++ b/OS/Nayoun/Process.md
@@ -0,0 +1,317 @@
+# 프로세스 개요
+
+## 프로세스
+
+> 실행 중인 프로그램
+>
+- **foreground process**
+ - 사용자가 보는 앞에서 실행되는 프로세스
+- **background process**
+ - 사용자가 보지 못하는 뒤편에서 실행되는 프로세스
+ - `daemon` - 유닉스 / `service` - 윈도우
+ - 사용자와 상호작용 X 정해진 일만 수행
+
+## PCB : Process Control Block
+
+> 모든 프로세스는 실행을 위해 CPU를 필요로 하지만, CPU 자원은 한정되어 있다.
+>
+- 그래서 프로세스가 돌아가며, ***한정된 시간 만큼만 CPU을 이용***할 수 있도록, `OS`는 `PCB`(Process Control Block)을 사용한다!
+- PCB는 **커널 영역에 생성**되며, OS는 PCB로 **프로세스를 식별** & **처리**하는데 필요한 정보를 판단한다.
+- PCB의 생명주기 = 프로세스의 생명주기
+
+
+
+
+- **Process State** : `new`, `ready`, `running`, `waiting`, `terminated` 상태 중 하나에 해당됨
+- **PID** : 프로세스를 식별하는 고유 번호
+- **Program Counter** : 메모리의 다음 명령어 주소를 저장함
+- **CPU registers** : `IR`(Instruction Register), `DR`(Data Register), `PC`(Program Counter)와 같은 저장공간이 포함됨
+- **CPU-scheduling information** : 프로세스 실행 순서를 정하는 정보
+- **Memory-management information** : 프로세스가 저장될 메모리에 관한 정보
+- **Accounting Information** : 프로세스의 실행, 시간 제한, 실행 ID 등에 사용되는 CPU양의 정보
+- **I/O status information** : 어떤 입출력 장치가 할당됨? 어떤 파일을 엶?
+
+## Context Switching
+
+> 하나의 프로세스 수행을 다시 시작하기 위해 기억해야 하는 정보들이다!
+>
+
+`Context`는 마지막에 명령을 수행했던 명령어 위치이고, `Context`는 `PCB`에 표시된다.
+
+
+
+- CPU core를 **다른 프로세스에게 양도**
+- 현재 **프로세스의 상태를 저장**
+- Context Switch 하게 되면 → 다른 Process Context를 복원
+
+**Pros :** 이를 통해 여러 프로세스들이 끊김 없이 빠르게 번갈아 가며 실행된다!
+
+**Cons :** 자주 일어나면 동시에 실행되는 것처럼 보이지만, `overhead`가 발생할 수 있다!
+
+## 프로세스의 메모리 영역
+
+> ***커널 영역에 PCB*** 생성 → ***사용자 영역에 프로세스***들이 배치됨.
+>
+
+사용자 영역은 크게 다음과 같이 구성되어 있다.
+
+
+
+1. **Text Section (정적 할당 영역!)**
+
+실행 가능한 코드를 저장하는 공간
+
+`read-only` 공간, 데이터가 아닌 CPU가 실행할 명령어가 담겨 있다!
+
+**2. Data Section (정적 할당 영역!)**
+
+전역 변수를 저장하는 공간
+
+**3. Heap Section (동적 할당 영역!)**
+
+프로그램 실행동안 동적으로 할당되는 변수가 저장되는 공간
+
+해당 메모리 공간이 반환해야 한다
+
+→ 반환하면? 더 이상 메모리 공간이 사용되지 않는 것!
+
+→ 만약에 반환이 안되면, `memory leak`이라는 문제가 발생한다.
+
+*낮은 주소에서 높은 주소로 할당*된다.
+
+**4. Stack Section (동적 할당 영역!)**
+
+함수가 실행되는 동안 지역변수가 저장되는 임시 공간, 대표적으로 함수 매개변수, 리턴 주소, 지역 변수 등이 포함됨
+
+*높은 주소에서 낮은 주소로 할당*된다.
+
+# 프로세스 상태와 계층 구조
+
+## 프로세스 상태
+
+
+
+
+> 여러 프로세스들이 빠르게 번갈아 가며 실행되는데, 이 과정에서 하나의 프로세스는 여러 상태를 거치며 실행된다.
+>
+
+프로세스가 가질 수 있는 상태는 다음과 같다.
+
+- **New** : 프로세스가 생성된 상태
+- **Ready** : 프로세스가 프로세서에 의해 실행되기를 기다리는 상태(언제라도 실행 가능) → **CPU를 할당받기 위해 대기 중**
+ - 준비상태의 `process`가 시작되면 → `Running`이 된다!
+- **Running** : 프로세스가 수행되는 상태
+- **Waiting** : 프로세스 이벤트가 발생되어 입/출력 완료를 기다리는 상태
+ - 왜 기다리는 상태도 추가가 되냐?
+ - → 입출력 작업은 CPU에 비해 속도가 느리므로, 입출력 작업을 요청한 프로세스는
+ - → 입출력 장치가 입출력을 끝낼 때까지 기다려야 한다!
+- **Terminated** : 프로세스 실행 종료 상태
+
+## 프로세스 계층 구조
+
+프로세스는 실행 도중 시스템 호출을 통해 다른 프로세스를 생성할 수 있다.
+
+1. `parent process` = 새 프로세스를 생성한 프로세스
+2. `child process` = `parent process`에 의해 생성된 프로세스
+
+**다른 프로세스 = 다른 `PID`를 가진다!**
+
+(일부 운영체제는 자식 프로세스의 `PCB`에 부모 프로세스의 `PID`인 `PPID`가 기록되기도 한다)
+
+***for example,***
+
+컴퓨터를 키고 → 로그인 창을 통해 성공적으로 로그인해서 → bash shell로 → vim이라는 문서 편집기를 실행하면,
+
+`최초의 프로세스 - 로그인 프로세스 - bash 프로세스 - vim 프로세스` 순으로 프로세스가 만들어진다.
+
+> **최초의 프로세스 → 항상 PID가 1번!**
+1. unix OS : `init`
+2. linux OS : `systemd`
+3. macOS : `launchd`
+>
+
+## 프로세스 생성 기법
+
+### `fork()`
+
+> 자신의 복사본을 자식 프로세스로 생성한다.
+>
+
+생성된 **자식 프로세스에는 → 부모 프로세스의 자원들 (메모리 내용, 열린 파일의 목록) 등이 상속**된다. 하지만 다른 프로세스이기 때문에 **`PID` or 저장된 메모리 위치가 다르다!**
+
+### `exec()`
+
+> 새로운 프로그램 내용으로 전환되어 실행하는 시스템 호출이다.
+>
+
+즉, `fork`을 통해 **복사본**이 만들어지면 → 자식 프로세스는 `exec` **시스템 호출을 통해 새로운 프로그램으로 전환**된다.
+
+`exec()`을 호출하면 → 코드 영역(text section)과 데이터 영역의 내용이 실행할 프로그램의 내용으로 바뀌고, 나머지 영역은 초기화된다!
+
+
+
+
+
+# Thread
+
+> `프로세스란`? → 실행되는 프로그램!
+`스레드란`? → 프로세스를 구성하는 실행의 흐름 단위!
+**하나의 프로세스는 → 여러 개의 스레드**를 가질 수 있다.
+스레드를 이용하면 → **하나의 프로세스에서 → 여러 부분을 동시에 실행**할 수 있다.
+>
+
+## Process & Thread
+
+> 기존에는 → 하나의 프로세스가 → 한번에 하나의 일만 처리했다 ⇒ **단일 스레드 프로세스**
+
+하지만 하나의 프로세스가 → 여러 일을 동시에 처리할 수 있다! (= 여러 명령어를 동시에 실행할 수 있다) ⇒ **멀티 스레드 프로세스!**
+>
+
+즉, 스레드는 프로세스 실행에 필요한 **최소한의 정보 (Program Counter을 포함한 Register, Stack) 만을 유지**한 채 **프로세스 자원을 공유**하며 실행된다!
+
+## MultiProcess & MultiThread
+
+> 여러 프로세스를 동시에 실행 : `MultiProcess`
+여러 스레드로 프로세스를 동시에 실행 : `MultiThread`
+>
+- 멀티 프로세스는 여러 프로세스를 동시에 실행하며, **프로세스들끼지 독립적**이기 때문에 → **하나의 프로세스에 문제가 생겼다고 해서, 다른 프로세스에 지장이 가지 않는다.**
+- 하지만 멀티 스레드는 여러 스레드로 프로세스를 동시에 실행하기 때문에, **하나의 스레드에 문제가 생기면 → 프로세스 전체에 문제가 생길 수 있다!**
+
+# IPC - Inter-Process Communication
+
+> 프로세스들은 독립적으로 실행되지만, 통신을 통해 **상호협력적으로** 실행 가능하다!
+>
+
+프로세스들은 IPC를 통해 데이터를 공유할 수 있고, 한 프로세스에서 다른 프로세스로 데이터를 전송하거나 수신할 수 있다.
+
+## IPC의 주요 모델
+
+
+
+- `shared memory`
+ - 메모리 위에 프로세스들간에 데이터를 공유할 수 있는 공유 메모리 영역을 사용하는 방법
+- `message passing`
+ - `message queue`를 놓고
+ - 프로세스들이 전송할 데이터를 `message queue`에 전송
+ - 프로세스들이 수신할 데이터를 `message queue`를 통해 받는다.
+
+### Shared Memory
+
+**같은 메모리를 직접 공유**
+
+
+
+생산자 - 소비자 문제가 발생함!
+
+> Multi-Processing or Multi-threading 환경에서 발생하는 고전적인 동기화 문제 중 하나이다.
+>
+> - 다수의 프로세스가 → 공유 자원에 접근할 때 발생.
+- Role
+ - 생산자 : 데이터 생성 & 공유 자원에 추가
+ - 소비자 : 공유 자원에 추가된 데이터를 꺼내서 사용
+ - 버퍼 : 공유 자원이고, 생산자가 만든 데이터를 임시로 보관.
+- 수행 과정
+ - 생산자 : 데이터를 생산해서 → 버퍼에 넣는다.
+ - 소비자 : 데이터를 꺼내서 → 사용한다.
+ - 생산자는 버퍼가 가득차면 → 대기한다. = `overflow`
+ - 소비자는 버퍼가 비어있으면 → 대기한다. = `underflow`
+
+***속도는 빠르지만, 동기화 문제에 대한 해결이 필요! → ex) mutex, semaphore, monitor***
+
+### Message Passing
+
+**메세지를 주고받음**
+
+
+
+- 개념
+ - 프로세스간에 데이터 전송 및 읽기와 같은 통신을 하기 위한 방법
+- 방법
+ - 메시지 큐
+ - 파이프
+ - 소켓
+ - RPC (Remote Procedure Call)
+- API
+ - `send(message, destination) or send(message)`
+ - `receive(message, host) or receive(message)`
+
+***속도는 상대적으로 느리지만, 동기화를 OS가 보장해준다! ex) message queue, pipe, socket, RPC***
+
+### Pipes
+
+**단방향 또는 양방향 채널을 생성해 2개 이상의 프로세스들이 서로 통신할 수 있도록 하는 IPC 기술의 한 종류.**
+
+
+
+- `System Call`을 사용하여 구현이 가능.
+- 장점
+ - 단순하고 효율적 (데이터를 전송할 때 최소한의 오버헤드)
+ - 신뢰 (에러 탐색 가능, 데이터 전달 보장 가능)
+ - 유연 (단방향 가능, 양방향 가능)
+- 단점
+ - 용량이 제한됨 → 한 번에 전송할 수 있는 데이터의 개수가 제한됨.
+ - 단방향성 → **단방향 파이프에서는 하나의 프로세스만이 데이터를 전송**할 수 있다.
+ - 동기화 → **양방향에서는 데이터 전송 순서가 동기화**되어야 한다.
+ - 제한된 확장성 → 파이프는 **동일 컴퓨터 내의 소수 프로세스 간의 통신으로 제한**됨 → **분산시스템에서는 단점!**
+ - 같은 컴퓨터에서 간단 & 효율 통신에서는 적합, 하지만 대규모 분산 시스템이나 양방향 통신에서는 적합하지 않는다.
+- 구현 시 고려할 점
+ - 단방향 or 양방향?
+ - 양방향이면 → 반이중? or 전이중?
+ - 통신 프로세스 사이에서 관계가 존재해야 하는가?
+ - 파이프가 네트워크를 통해 통신하는가?
+- 종류
+ - **익명 파이프 (unamed pipe)**
+
+
+ - only 단방향으로, 부모 → 자식 프로세스 간 통신한다.
+ - FIFO 방식으로 임시 공간인 파이프를 기반으로 데이터를 주고 받고, 단방향 방식의 읽기 전용, 쓰기 전용 파이프를 만들어서 작동한다.
+ - **명명 파이프 (named pipe)**
+ - 파이프 서버와 하나 이상의 파이프 클라이언트 간의 통신을 위한 명명된 단방향 또는 양방향 파이프를 말한다.
diff --git a/OS/Nayoun/Scheduling.md b/OS/Nayoun/Scheduling.md
new file mode 100644
index 0000000..6abdfee
--- /dev/null
+++ b/OS/Nayoun/Scheduling.md
@@ -0,0 +1,144 @@
+OS가 프로세스에게 공정하고 합리적으로 CPU 자원을 배분하는 것.
+
+## 프로세스 우선순위
+
+프로세스마다 우선순위가 다르다. ex) I/O 프로세스는 가장 우선순위가 높다.
+
+### 프로세스의 종류
+
+1. **I/O bound process**
+ 1. `입출력 작업`이 많은 프로세스 (비디오 재생, 디스크 백업 작업)
+ 2. 실행 상태보다 입출력을 위한 대기 상태에 더 많이 머무른다.
+2. **CPU bound process**
+ 1. `CPU 작업`이 많은 프로세스 (수학 연산, 컴파일, 그래픽 처리)
+ 2. 대기 상태보다 실행 상태에 더 많이 머무른다.
+
+
+
+`CPU 집중 프로세스`와 `입출력 집중 프로세스`가 동시에 CPU 자원을 요구하면 → 입출력 프로세스를 빨리 실행 시켜서 입출력 장치를 끊임없이 작동하는 것이 좋다!
+
+⇒ 이렇게 모든 프로세스가 CPU를 차례대로 사용하는 것보다, 각각의 상황에 맞게 CPU를 분배하는 것이 좋다!
+
+⇒ 이를 위해 OS는 프로세스의 PCB마다 우선순위를 부여한다
+
+## Scheduling Queue
+
+> OS가 매번 모든 PCB를 검사해서 먼저 자원을 이용할 프로세스를 결정하는 것은 비효율적이다.
+>
+
+왜냐?
+
+1. CPU를 원하는 프로세스는 한 두개가 아니며, 언제든 새로운 프로세스가 생길 수 있다.
+2. 메모리에 적재되고 싶어하는 프로세스, 특정 입출력장치와 보조기억장치를 사용하길 원하는 프로세스도 여러 개가 있을 수 있다.
+
+⇒ 따라서 OS는 ***CPU를 사용하고 싶은 프로세스 → 메모리에 적재되고 싶은 프로세스 → 특정 입출력장치 사용하고 싶은 프로세스*** 순으로 줄 세움
+
+⇒ 이것을 `Scheduling Queue`로 구현하고 관리한다!
+
+### Queue의 종류
+
+
+1. **Ready queue → CPU를 이용하기 위해 기다리는 줄**
+2. **Waiting Queue → 입출력장치 이용하기 위해 기다리는 줄**
+
+## Preemptive / Non-Preemptive
+
+
+### Preemptive Scheduling
+
+> 하나의 프로세스가 다른 프로세스가 사용 중인 CPU의 자원을 요청할 때, OS로부터 자원을 강제로 뺴앗아 다른 프로세스에 할당할 수 있는 스케줄링 방식
+>
+- 하나의 프로세스가 자원 독점 X
+ - **Pros :** 한 프로세스의 자원 독점 막고 프로세스들에 자원 골고루 배분하지만,
+ - **Cons :** Context Switching 과정에서 Overhead가 발생할 수 있다.
+
+### Non-Preemptive Scheduling
+
+> 하나의 프로세스가 다른 프로세스가 사용 중인 CPU의 자원을 요청할 때, 그 프로세스가 종료(terminated) or 대기(waiting)에 접어들기 전까지 다른 프로세스가 끼어들 수 없는 스케줄링 방식
+>
+- 하나의 프로세스가 자원 독점 O
+ - **Pros :** Context Switching 과정에서 Overhead가 적지만,
+ - **Cons :** 모든 프로세스들이 골고루 자원을 사용할 수 없다.
+
+# CPU Scheduling Algorithm
+
+## FCFS(First Come First Served Scheduling)
+
+> **Non-Preemptive :** Ready Queue에 삽입된 순서대로 프로세스들을 처리
+>
+
+즉, CPU가 먼저 요청한 프로세스부터 CPU를 할당한다.
+
+- **Pros : 가장 공정해보이지만,**
+- **Cons : 프로세스들이 기다리는 시간이 매우 길어질 수 있다.**
+
+`convoy effect` : CPU 버스트가 높은 프로세스가 `Ready Queue` 앞에 오면 그 뒤에 CPU 버스트가 더 낮은 프로세스가 기다려야 한다.
+
+ex) A (17ms) → B (5ms) → C (2ms) → C는 2ms의 실행 시간때문에 22ms의 대기 시간을 거쳐야 한다.
+
+## SJF(Shortest Job First Scheduling)
+
+> **Non-Preemptive or Preemptive :** convoy effect를 방지하기 위해 나타남 → ***최단 시간 프로세스***부터 처리!
+>
+- Preemptive로 구현한 것이 SRT!
+
+## RRB(Round Robin Scheduling)
+
+> FCFS + time slice (=각 프로세스가 CPU를 사용할 수 있는 정해진 시간)
+>
+- `time slice`가 많으면 : FCFS와 비슷해짐 → `convoy effect`가 생길 수 있다!
+- `time slice`가 적으면 : `Context Switching`에 발생하는 비용이 크다 → CPU에 처리되는 일보다 프로세스를 전환하는데 더 많은 비용이 든다!
+
+## SRT(Shortest Remaining Time)
+
+> `SJF` + `RRB`
+>
+
+⇒ 즉, 프로세스들은 정해진 `time slice`만큼 `CPU`를 사용하지만, `CPU`를 사용할 다음 프로세스로는 ***남아있는 작업 시간이 가장 적은*** 프로세스가 선택된다.
+
+## Priority Scheduling
+
+> 프로세스마다 우선순위를 부여하여 → 가장 높은 우선순위의 프로세스부터!
+>
+- `SJF` → 작업 시간이 짧은 프로세스에 높은 우선순위를 부여
+- `SRT` → 남은 시간이 짧은 프로세스에 높은 우선순위 부여
+
+**Prob :** `starvation` 현상 : 우선순위가 낮은 프로세스가 우선순위가 높은 프로세스들에 의해 계속 연기되는 현상
+
+**Sol :** `aging` → 오랫동안 기다린 프로세스의 우선순위를 높이기!
+
+## Multilevel Queue Scheduling
+
+
+> **Preemptive :** 우선순위 별로 ready queue를 여러 개 사용
+>
+
+즉, `queue`에 우선순위를 매겨서, 가장 높은 우선순위 큐에 있는 프로세스 먼저 처리한다.
+
+- **Pros :** 프로세스 유형별로 우선순위 구분하여 실행 가능, 큐별로 타임 슬라이스 여러 개 지정하여 다른 스케줄링 알고리즘 사용
+- **Cons :** 프로세스들이 큐 사이 이동을 못한다 → 이것을 해결한 것이 `Multilevel Feedback Queue Scheduling`!
+
+아래 2개로 분할한다.
+
+1. `foreground queue` → cpu burst가 짧은 queue!
+ 1. `Round Robin`
+2. `background queue` → batch 등 긴 시간을 필요로 하는 작업!
+ 1. `FCFS`
+
+## Multilevel Feedback Queue Scheduling
+
+> Multilevel Queue의 기아 현상을 해결했다!
+>
+
+어떻게? queue사이에 프로세스를 이동함으로써!
+
+- aging 기법을 활용해서, CPU 집중 프로세스 (priority queue에서 오래 기다리는 프로세스)를 점점 아래로 내리고, 새로 준비 상태가 된 프로세스를 위로 올린다.