Skip to content

Commit 08aad45

Browse files
authored
Merge pull request #59 from java-squid/sigrid
[운영체제] 11주
2 parents bd551d9 + da9be3e commit 08aad45

4 files changed

Lines changed: 330 additions & 0 deletions

File tree

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# 데드락이란 무엇인가
2+
## 정의
3+
* 운영체제에서 데드락이란, 시스템 자원에 대한 요구가 엇갈린 상태를 의미한다.
4+
* 둘 이상의 프로세스가 다른 자원의 프로세스를 점유하다보니, 무한 대기(루프) 상태에 빠지게 되는 것을 의미한다.
5+
* 즉, Deadlock은 다른 프로세스 또는 쓰레드가 소유한 자원을 요청한 행위가 서로에게 행해져 모든 프로세스 또는 쓰레드가 block이 되는 상태를 의미한다.
6+
* A lock occurs when multiple processes try to access the same resource at the same time.
7+
* One process loses out and must wait for the other to finish.
8+
* A deadlock occurs when the waiting process is still holding on to another resource that the first needs before it can finish.
9+
## 예시 1
10+
![](https://i.imgur.com/MEXzKoF.png)
11+
* 쓰레드 T0이 리소스 1에 대한 Lock이 걸려 있는 상태이지만, 해당 쓰레드가 모든 일을 끝마치려면 리소스 2에 대한 자원이 필요한 상태이다.
12+
* 쓰레드 T1이 리소스 2에 대한 Lock이 걸려 있는 상태이지만, 해당 쓰레드가 모든 일을 끝마치려면 리소스 1에 대한 자원이 필요한 상태이다.
13+
## 예시 2
14+
### 서로가 사용하고 있는 Semaphore를 요청하여 Block에 걸리게 되는 경우
15+
* 다음과 같이 두 개의 코드가 주어졌다고 생각하자.
16+
```
17+
Process1
18+
owns lock A
19+
requests lock B
20+
```
21+
```
22+
Process2
23+
owns lock B
24+
requests lock A
25+
```
26+
* 여기서 프로세스 1은 lock A를 갖고 있는데, 이는 A에 대한 세마포어(semaphore)를 갖고 있다는 뜻이다. 이와 달리, 프로세스 2는 lock B를 갖고 있는데, 이는 B에 대한 세마포어(semaphore)를 갖고 있다는 뜻이다.
27+
* 세마포어는 한 곳에서 사용 중이라면, 다른 프로세스를 차단하는 목적으로 사용된다. 프로세스 1이 lock B를 요청할 경우, lock B는 현재 사용 중이므로 프로세스 1은 lock B가 release되기 전까지 Block 상태에서 대기하게 된다.
28+
* 프로세스 2도 마찬가지이다. lock A를 요청할 경우, 현재 lock A는 사용 중이므로 프로세스 2는 lock A가 release되기 전까지 Block 상태에서 대기하게 된다.
29+
![](https://i.imgur.com/n86eluU.png)
30+
## 예시 3
31+
### Recursive Lock
32+
* 프로세스 1이 한 semaphore를 갖고 있다. 해당 semaphore는 다른 프로세스가 접근할 수 없게 된다. 이 떄, 프로세스 1은 똑같은 semaphore에 접근을 요청한다. 이러한 경우, 해당 semaphore는 접근할 수 없음으로 데드락에 빠지게 된다.
33+
![](https://i.imgur.com/a6f89wO.png)
34+
## 예시 4
35+
### 범죄자와 경찰
36+
![](https://i.imgur.com/lWTXmAi.png)
37+
* Imagine a criminal holds an hostage and against that, a cop also holds an hostage who is a friend of the criminal. In this case, criminal is not going to let the hostage go if cop won't let his friend to let go. Also the cop is not going to let the friend of criminal let go, unless the criminal releases the hostage. This is an endless untrustworthy situation, because both sides are insisting the first step from each other.
38+
* So simply, when two threads needs two different resources and each of them has the lock of the resource that the other need, it is a deadlock.
39+
40+
## Deadlock의 상태
41+
* 일반적으로 프로세스는 리소스를 사용하기 위해서는 사전에 요청을 거쳐야 하고, 다음과 같은 과정을 거친다.
42+
* Request: 리소스 사용을 요청할 때 즉각 받아들여지지 않는다면, 프로세스는 리소스 사용이 가능해질 때까지 대기해야 한다. 주된 함수 연산으로는 ```call(), malloc()``` 등이 있다.
43+
* Use: 쓰레드가 자원을 사용하는 단계이다. 프린터를 사용하고 있거나, 파일을 읽고 있다.
44+
* Release: 프로세스는 리소스 사용을 중지(relinquish)한다. 따라서 해당 자원은 다른 프로세스가 사용 가능해진다. 주된 함수 연산으로는 ```close(), free(), delete()``` 등이 있다.
45+
* 커널이 매니징하느냐? 애플리케이션이 매니징하느냐? 에 따라 차이가 있는데 아무래도 커널이 관리해주는 것이 개발자 입장에서는 불필요한 소요를 줄이는 일이지 않을까 싶다.
46+
* 커널이 매니징한다는 것은, 커널이 어떤 리소스가 free이고 어디에 allocate 되어 있고를 모두 파악한다는 소리다. 현재 process의 queue를 관리해서 어느 프로세스가 다음 리소스의 사용을 원하는 지를 확인한다.
47+
* Application이 매니징한다는 것은, mutex나 wait(), signal() 함수 호출로 인하여 컨트롤 되는 것을 의미한다.
48+
49+
## Deadlock의 4가지 조건
50+
* Mutual Exclusion: 최소 한 개의 리소스가 non-sharable한 상태로 특정한 프로세스나 쓰레드에 의해 사용되고 있어야 한다. 만약 다른 프로세스가 해당 리소스 사용 요청을 보내면, 해당 프로세스는 리소스가 사용 가능할 때까지 기다려야 한다.
51+
* Hold and Wait: 프로세스는 동시에 하나의 리소스를 갖고 있으면서 또 다른 프로세스나 쓰레드가 점유하고 있는 리소스 사용을 요청할 수 있다.
52+
* No Preemption: 임의의 프로세스가 리소스를 소유한다고 가정하자. 그렇다면 다른 프로세스나 쓰레드는 해당 프로세스나 쓰레드가 스스로 리소스를 내려 놓기 전까지는 강제로 끌어내릴 수 없다.
53+
* Circular wait: A set of processes { P0, P1, P2, . . ., PN } must exist such that every P[ i ] is waiting for P[ ( i + 1 ) % ( N + 1 ) ]. (해당 조건은 Hold and Wait 조건을 support하는 것 같다)
54+
55+
## 데드락, 어떻게 해결할 것인가
56+
## 데드락을 예방 Prevention 하기
57+
* Not allowing the system to get into a deadlocked state. 위의 4가지 조건을 모두 충족시키지 않으면서 가능하다.
58+
* 자원의 상호 배제 조건 방지 : 한 번에 여러 프로세스가 공유 자원을 사용할 수 있게 한다. 다만, 추후 동기화 문제가 생길 수 있다.
59+
* 점유 대기 조건 방지 : 프로세스 실행에 필요한 모든 자원을 한꺼번에 요구하고 허용할 때까지 작업을 보류해서, 나중에 또다른 자원을 점유하기 위한 대기 조건을 성립하지 않도록 한다.
60+
* 비선점 조건 방지 : 이미 다른 프로세스에게 할당된 자원이 선점권이 없다고 가정할 때, 높은 우선순위의 프로세스가 해당 자원을 선점할 수 있도록 합니다.
61+
* 순환 대기 조건 방지 : 자원을 순환 형태로 대기하지 않도록 일정한 한 쪽 방향으로만 자원을 요구할 수 있도록 합니다.
62+
* 데드락 예방(Prevention)은 시스템의 처리량이나 효율성을 떨어트리는 단점이 있다.
63+
64+
### 데드락 회피(avoidance)
65+
* 시스템의 프로세스들이 요청하는 모든 자원을, 데드락을 발생시키지 않으면서도 차례로 모두에게 할당해 줄 수 있다면 안정 상태(safe state)에 있다고 한다.
66+
* 그리고 이처럼 특정한 순서로 프로세스들에게 자원을 할당, 실행 및 종료 등의 작업을 할 때 데드락이 발생하지 않는 순서를 찾을 수 있다면, 그것을 안전 순서(safe sequence)라고 부른다.
67+
* 불안정 상태는 안정 상태가 아닌 상황을 말한다. 데드락 발생 가능성이 있는 상황이며, 교착 상태(데드락)는 불안정 상태일 때 발생할 수 있다.
68+
* 회피 알고리즘은 자원을 할당한 후에도 시스템이 항상 Safe state에 있을 수 있도록 할당을 허용하자는 것이 특징이다.
69+
* 은행원 알고리즘: 은행원 알고리즘의 경우, 이처럼 미리 최대 자원 요구량을 알아야 하고, 할당할 수 있는 자원 수가 일정해야 하는 등 사용에 있어 제약조건이 많고, 그에 따른 자원 이용도 하락 등의 문제가 있을 수 있다.
70+
71+
### 데드락 탐지 및 회복(Detection)
72+
* 탐지
73+
* Allocation, Request, Available 등으로 시스템에 데드락이 발생했는지 여부를 탐색
74+
* 현재 시스템의 자원 할당 상태를 파악
75+
* 회복
76+
* 순환 대기에서 벗어나 데드락으로부터 회복하기 위한 방법을 사용
77+
* 단순히 프로세스를 1개 이상 중단시키기: 상태에 빠진 모든 프로세스를 중단하거나, 프로세스를 하나씩 중단 시킬 때마다 탐지 알고리즘으로 데드락을 탐지하면서 회복시키는 방법: 매번 탐지 알고리즘을 호출 및 수행해야 하므로 부담이 되는 작업일 수 있음
78+
* 자원 선점하기: 프로세스에 할당된 자원을 선점해서, 교착 상태를 해결할 때까지 그 자원을 다른 프로세스에 할당해 주는 방법
79+
80+
#### Reference
81+
* 더 알아보기 좋은 자료(영문): https://www.cs.uic.edu/~jbell/CourseNotes/OperatingSystems/7_Deadlocks.html
82+
* https://stackoverflow.com/questions/34512/what-is-a-deadlock
83+
* https://chanhuiseok.github.io/posts/cs-2/
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# 리눅스 메모리 관리 기법 간단히 알아보기
2+
* 여러 프로세스를 동시에 실행하는 경우 프로세스 크기가 서로 달라 메모리를 어떻게 나누어 사용할지에 대한 문제가 생긴다.
3+
## 가상 메모리 Virtual Memory
4+
* 가상 메모리는 메모리 사용량이 늘어나면서, HDD/SDD의 일부를 확장 RAM처럼 사용할 수 있도록 하는 기술이다.
5+
* 커널은 실제 메모리(RAM)에 올라간 메모리 블록들 중 당장 쓰이지 않는 것을 디스크에 저장한다. 이를 통하여 사용 가능한 메모리 영역을 늘릴 수 있다.
6+
* 만약 디스크에 저장되었던 메모리 블록이 다시 필요하게 되면, 해당 블록을 RAM에 다시 올린다. 대신 다른 블록을 디스크로 내린다.
7+
* 하지만 HDD/SDD를 읽고 쓰는 시간은 RAM보다 약 천배 정도 느리기 때문에 프로그램 실행은 그만큼 더디게 된다.
8+
* 가상 메모리로 쓰이는 HDD/SDD의 영역을 Swap space라고 한다.
9+
* CPU가 특정 프로세스의 어떤 공간을 참조할 때는 우선 가상 주소를 먼저 참조하고, 가상 주소에 해당하는 실제 물리 주소를 참조하게 된다.
10+
## MMU
11+
* CPU가 가상 메모리에 접근하기 위해 물리 메모리의 가상 주소를 참조할 때마다 매번 이를 물리 주소로 변환을 하게 되니까 이 시간을 짧게 하려고 MMU라는 하드웨어 칩의 지원을 받는다. MMU는 가상 주소를 물리 주소로 빠르게 변환해주는 역할을 한다.
12+
* 프로세스 생성 시 물리 메모리 레지스터(PCB)에 페이지 테이블 정보가 생성된다.
13+
* PCB 등에서 해당 페이지 테이블에 접근이 가능하고, 관련 정보는 물리 메모리에 적재한다.
14+
* 프로세스 구동 시, 해당 페이지 테이블의 base 주소 (시작 주소)가 별도의 레지스터(CR3)에 저장된다.
15+
* 즉 CPU가 가상 주소에 접근 시, MMU가 CR3를 통해 페이지 테이블 base 주소에 접근해서 물리 주소를 가져온다.
16+
17+
## 연속 할당 기법
18+
* 프로그램 전체를 하나의 공간에 연속적으로 할당하는 기법이다.
19+
* 고정 분할 할당(정적 할당)
20+
* 프로그램 전체가 주 기억장치에 위치해야 한다.
21+
* 주기억장치 고정된 크기로 분할한다. 프로그램이 분할된 영역보다 클 경우 들어갈 수 없다. 내부, 외부 단편화 발생하여 낭비가 많다.
22+
* 가변 분할 할당(동적 할당)
23+
* 고정 분할 기법처럼 미리 분할해놓는 것이 아니라 프로그램을 주기억장치에 적재 시 필요한 크기로 분할한다. 고정 분할 기법보다 단편화를 줄일 수 있지만 영역과 영역 사이 단편화가 발생할 수 있다.
24+
25+
## 비연속 할당 기법(분산 할당 기법)
26+
* 프로그램을 특정 단위의 조각으로 나누어 주기억장치 내에 분산하여 할당한다.
27+
* 하나의 프로세스에서 특정 시간 동안 쓰는 메모리 영역은 4GB 중 아주 일부분이기 때문에 일부분만 실제 물리 메모리에 올려놓고 쓰자는 것이 가상 메모리의 컨셉이다.
28+
* 이 때 정도의 사이즈만큼 메모리에 올릴 지에 대한 결정이 필요하다(100MB? 1GB? 등). 이를 페이지(page)라는 단위로 다루겠다고 하는 것이 바로 페이징 시스템이다.
29+
### 페이징
30+
* 가상 메모리를 일정한 크기로 나눈 블록
31+
* 크기가 동일한 페이지 단위
32+
* 가상 주소 공간과 이에 매칭되는 물리 주소 공간을 관리
33+
* 페이지 번호를 기반으로 가상 주소와 물리 주소의 매핑 정보를 기록하고 사용
34+
* 리눅스의 경우 4GB의 가상 메모리를 4KB 단위로 쪼개서 페이징하고 페이지 번호를 붙임
35+
* 페이지 단위로 물리 메모리에 넣고, 해당 데이터를 찾을 때에도 페이지 번호를 기반으로 주소를 찾게 된다.
36+
37+
### 프레임
38+
* 물리 메모리를 일정한 크기로 나눈 블록(page와 동일한 크기)
39+
* 프로세스(4GB)의 PCB(Process Control Block)에 Page Table 구조체를 가리키는 주소가 들어 있음
40+
* Page Table에는 가상 주소와 물리 주소 간 매핑 정보가 있음
41+
![](https://i.imgur.com/TS55cDT.png)
42+
43+
### 페이지 테이블
44+
* 가상 주소에 있는 페이지 번호와 해당 페이지의 첫 물리 주소 정보를 매핑한 표
45+
```
46+
가상 주소 v = (p, d)라면
47+
p: 페이지 번호
48+
d: 페이지 처음부터 떨어진 정도 (위치)
49+
```
50+
51+
## 세그멘테이션 기법
52+
* 가상 메모리를 서로 크기가 다른 논리적 단위인 세그먼트(Segment)로 분할하는 기법
53+
* 페이징 기법에서는 가상 메모리를 같은 크기의 블록으로 분할하는 것과 대조됨
54+
* [외부 단편화](https://m.blog.naver.com/rbdi3222/220623825770)가 일어나기 쉽다. 평균 세그먼트의 크기가 작을 수록 외부 단편화 문제는 줄어든다.
55+
### 주소 변환
56+
* 주소 변환을 위해 세그먼트의 위치 정보를 가지고 있는 세그먼테이션 매핑 테이블이 필요하다.
57+
* 이 테이블은 limit(세그먼트 크기)과 base(물리 메모리상의 시작 주소 정보)를 갖는다.
58+
* 가상 주소를 (S,D)로 표현한다. S는 세그먼트의 No이고, D는 세그먼트 시작 지점에서 해당 주소까지의 거리를 의미한다. 물리주소는 ```base[S]+D``` 로 계산한다.
59+
```
60+
No limit base
61+
0 280 120
62+
1 120 450
63+
2 100 630
64+
… … …
65+
```
66+
* 논리주소 (2, 100) => 물리주소 630+100 = 730번지
67+
* 논리주소 (1, 200) => 거리가 세그먼트의 크기(120)보다 크기 때문에 메모리 관리자는 해당 프로세스를 강제 종료한다. (trap(사용자가 의도치 않게 일으키는 인터럽트)을 발생시킴)
68+
69+
### 참고: 단편화 문제 Fragmentation Problem
70+
* 내부 단편화 문제(Internal Fragmentation Problem) - (페이지 기법)
71+
* 페이지 블록만큼 데이터가 딱 맞게 채워져 있지 않을 때 공간 낭비
72+
* 외부 단편화 문제(External Fragmentation Problem) - (세그멘테이션 기법)
73+
* 물리 메모리가 원하는 연속된 크기의 메모리를 제공해주지 못하는 경우
74+
75+
## 참고
76+
* http://egloos.zum.com/sweeper/v/2988689
77+
* https://velog.io/@gndan4/OS-%EA%B0%80%EC%83%81-%EB%A9%94%EB%AA%A8%EB%A6%AC
78+
* https://colinch4.github.io/2020-02-02/%EB%A9%94%EB%AA%A8%EB%A6%AC-%ED%95%A0%EB%8B%B9-%EA%B8%B0%EB%B2%95/
79+
* https://higunnew.tistory.com/61
80+
* https://www.geeksforgeeks.org/difference-between-paging-and-segmentation/

0 commit comments

Comments
 (0)