공부/운영체제

데드락(Deadlock)

sudo 2022. 9. 2. 17:32

데드락(Deadlock)이란?

- 프로세스나 쓰레드가 얻고자 하는 자원을 얻지 못해, 교착 상태에 빠진 것

 

데드락 발생 조건

아래 4개의 조건 모두를 만족한다면 잠재적으로 데드락이 발생할 가능성이 있다.

 

1. 상호 배제(Mutual Exclusion)

- 자원은 한번에 하나의 프로세스나 쓰레드만 사용할 수 있다

 

2. 점유 대기

- 프로세스가 최소 하나의 할당된 자원을 갖고 있으면서 다른 자원을 기다린다

 

3. 비선점

- 다른 프로세스가 갖고 있는 자원을 강제로 빼앗을 수 없다

 

4. 순환 대기

- 각 프로세스는 다음 프로세스가 점유중인 자원을 순환적으로 대기중이다. 예를 들어서 P1, P2, P3 프로세스가 있고, P1은 R1, P2은 R2, P3는 R3 이렇게 각각 리소스를 점유중일 때, P1는 R2을 기다리고 있고, P2은 R3를 기다리고, P3는 다시 R1을 기다리고 있다면 순환 대기를 만족한다. 이 상황이라면 데드락에 걸린다

출처 : https://velog.io/@ryalya/iOS-CS-Study-Deadlock%EB%8D%B0%EB%93%9C%EB%9D%BD-%EA%B5%90%EC%B0%A9%EC%83%81%ED%83%9C%EB%9E%80

 

데드락 방지

데드락이 발생하기 전 예방하는 방법은 위에서 말한 조건이 성립하지 않게하면 된다

 

1. 상호 배제 조건 제거

-  한번에 여러 프로세스나 쓰레드가 공유 자원을 쓸 수 있게 한다. 단, Data race가 발생할 수 있다

 

2. 점유 대기 조건 제거

-  프로세스 실행 전 필요한 자원을 한번에 모두 할당

 

3. 비선점 조건 제거

-  자원을 이미 갖고 있는 프로세스나 쓰레드가 다른 자원을 요구할 때, 이미 갖고 있는 자원을 반납

 

4. 순환 대기 조건 제거

-  자원을 순환 형태로 요구하지 않도록 자원을 한쪽 방향으로만 요구하도록 한다. 위의 순환 대기 예시로 말하면, P3는 R1을 요구하지 못하도록 한다

 

하지만 이런 예방법을 지키려고 하다보면 효율성이 떨어지는 코드를 작성할 수도 있고 기아가 발생할 수도 있다

 

데드락 회피 방법

Deadlock이 발생할 가능성이 있는 경우엔 자원을 아예 할당해주지 않는 방법.

먼저 회피 알고리즘을 배우기 전에 숙지해야할 용어가 있다

 

  • 안전 순서열(Safe Sequence) : 데드락이 발생하지 않는 프로세스별 자원 할당 순서. 수식으로 표현하면 <P0,...Pn> 순서로 프로세스가 자원을 요청할 때 Pi( 0 <= i <= n) 의 요청이 현재 가용한 자원 + Pj (j < i)가 사용중인 자원들로 해결될 때 <P0, ... Pn>은 안전 순서열이 될 수 있다 
  • 안전 상태(Safe State, <-> Unsafe State) : 안전 순서열이 존재하는, 그러니까 프로세스가 요구하는 양 만큼 자원을 할당해줄 수 있고 그렇게 해도 데드락이 생길 가능성이 없는 상태를 말한다

출처 :&nbsp;https://home.cs.colorado.edu/~rhan/CSCI_3753_Spring_2005/CSCI_3753_Spring_2005/Lectures/03_01_05_deadlock.pdf

 

1. 자원 할당 그래프 알고리즘(Resource Allocation Graph Algorithm)

1개의 자원 타입만 존재할때 사용 가능. 자원 할당 그래프를 그렸을 때 Cycle이 안생기면 Safe하다는 의미

https://steady-coding.tistory.com/547

R->P 실선은 프로세스에 자원이 할당됐음을 의미

P->R 실선은 프로세스가 자원을 요청했음을 의미

점선은 프로세스가 자원을 미래에 요청할 수 있음을 의미 

2. 은행원 알고리즘(Banker's Algorithm)

자원 할당 그래프 알고리즘과 달리 여러개의 자원 타입이 존재할 때 사용 가능

은행원 알고리즘은 두 개의 알고리즘으로 이루어져 있다. 첫번째는 Resource-Request Algorithm이고 두번째는 Safety Algorithm이다.

 

Resource-Request Algorithm의 내용은 결국 Pi가 특정 타입의 Resource Instance를 요청했을 때, Resource 할당이 가능한 상태인지 체크하고 가능하면 할당해주고 각종 정보를 Update하는 것이고, Safety Algorithm은 Resource-Request Algorithm으로 자원을 할당해줬을 때 Safe State인지 체크하고, 맞다면 Safe Sequence를 찾는 알고리즘이다.

 

학부때 수업 자료를 가져와보자

 

 

Resource-Request Algorithm

강의자료에 워낙 설명되어 있는데 간략하게 좀 더 설명하면, 초기 상태의 자원은 (A, B, C) 순서로 (10, 5, 7) 이었으나 5개의 프로세스에 부분적으로 할당하고 남은건 (3, 3, 2)이다 Safety Algorithm에 Step1에 의해서 Work = (3, 3, 2)가 되고, 모든 프로세스들의 완료 상태를 나타내는 Finish는 모든 i에 대해서 false로 초기화 된다. 이 상태에서 Step2에 나와있듯이,  Finish == false이고, Need < Work 인 프로세스중 하나를 찾으면 P1이 있다. Step3에 의해 Work = Work + Allocation = (5, 3,2)가 되고, Finish 벡터의 i번째 인덱스를 true로 만든다. 이 과정을 5개 프로세스의  Finish벡터가 true가 될 때 까지 한다. 모든 프로세스의 Finish 벡터가 true가 된다면 safe state에 있다는 것이다

 

여기서 1개의 예시를 추가하고 2개의 알고리즘을 또 적용한 사진도 있어서 추가한다

 

 

 

중요한 점은 위에서 소개한 Resource-Allocation Graph Algorithm이나 Banker's Algorithm은 데드락을 회피하는 방법이고, 앞서 설명한 데드락을 방지하는 것과는 다른 것이다.

 

데드락 방지(Deadlock Prevention)는

  • 위에서 말한 데드락 방지를 위한 4개의 조건중 적어도 하나만 만족하면 달성할 수 있고
  • 데드락 방지를 위해서 현재 이용 가능한 자원의 상황이나, 할당된 자원의 양을 미리 알 필요도 없다

데드락 회피(Deadlock Avoidance)는

  • 시스템이 Unsafe state(= 데드락이 생길 가능성이 존재하는 상태)로 들어가는 것을 방지하는 것이고
  • 현재 이용 가능한 자원의 상황이나, 할당된 자원의 양, 미래에 요청할 자원들을 미리 알아야 한다

이 두가지를 조금이나마 명쾌하게 설명한 Quora에 답변이 있었다

https://www.quora.com/What-is-the-difference-between-deadlock-detection-and-deadlock-avoidance

 

데드락 탐지 방법

Single Instance of Resource Type 경우

- wait-for 그래프를 그려서 cycle 여부가 있는지 확인

Resource-Allocation Graph에서 Pi -> R과 R->Pj는 wait-for graph에서 Pi->Pj로 Collapsing 가능

DFS로 wait-for graph의 vertex마다 cycle 여부를 검사해보니까 시간 복잡도는 O(n^2)

Multiple Instance of Resources Type 경우

Banker's Algorithm과 유사한 알고리즘을 사용한다. 단 여기선 Banker's Algorithm에서 사용하면 Process별 Max(최종으로 요구하는 자원의 총량)이 없는데 그 이유는 지금 Deadlock Detection은 당장 데드락이 발생한지만 판단하고, 미래에는 어떻게 될지까지는 판단하지 않기 때문이다. 이것이 Deadlock Avoidance와 Deadlock Detection의 차이이기도 하다.  

Banker's Algorithm과 살짝 다른 점은, Banker's Algorithm은 지금 이미 할당된 자원 상태(Allocation)과 작업을 끝마치기 위해 필요한 추가적으로 필요한 자원의 총량(Need)이 있었는데 Detection Algorithm에서는 단지 지금 한번 요청하는 자원을 양(Request)가 있을 뿐이다.

알고리즘 자체는 Banker's Algorithm과 유사하다

 

데드락 상태로부터 회복

방법1. 사용자가 직접 처리

교착 상태가 걸려있는 프로세스중에서 하나를 사용자가 교착 상태 해결을 위해 종료하면 된다

 

방법2. 시스템에 의한 처리

  • 2-1. 프로세스 중지

교착 상태에 걸린 프로세스를 중지 시키는 방법. 프로세스를 하나 하나 차례대로 중지 시키는 방법도 있고, 모든 프로세스를 중지 시키는 방법도 있다. 하나 하나 중지시키면 프로세스를 중지 시키는데 드는 비용은 더 적게 들지만, 하나 중지할 때 마다 데드락 탐지 알고리즘을 써야 하니 그에 따른 비용은 더 클 수 밖에 없다. 모든 프로세스를 중지 시키면 확실하게 데드락을 해결할 수 있겠으나, 모든 프로세스를 중지해야하는 만큼 중지하는데 드는 비용은 클 수 밖에 없다

  • 2-2. 자원 선점

데드락이 해결될 때 까지 프로세스들이 점유 중인 자원을 강제로 빼앗아서 필요로 하는 프로세스에 주는 방법. 단 아래와 같은 이슈를 고려해야 한다

  • 기아(Starvation) : 매번 희생될 프로세스가 같다면 그 프로세스는 자원을 계속해서 뺏기게 된다. 그렇게 되지 않기 위해 지금까지 희생될 프로세스로 선택된 횟수를 따로 저장하고 그걸 기준으로 희생될 프로세스를 선택하는게 좋다.
  • 희생될 프로세스 선택 : 데드락 회복을 위해 필수적으로 중지 되어야할 프로세스의 수를 최소화 하려면 특정 기준을 갖고 희생될 프로세스를 선택해야 한다. 예를 들면, 지금갖고 있는 자원의 수나 실행된 시간
  • Rollback : 프로세스로부터 자원을 선점하려면 안전한 시점으로 롤백 시킨 후 선점해야한다. 따라서 어떤 시점으로 롤백 시킬 것인지도 고려해야 한다

'공부 > 운영체제' 카테고리의 다른 글

시스템 콜(System Call)  (0) 2022.09.06
Spin Lock, Semaphore, Mutex  (0) 2022.09.02
쓰레드(Thread), 프로세스(Process)란?  (2) 2022.09.01
Windows에서의 동기화 기법  (0) 2022.01.22