[운영체제] 교착상태, 데드락 : Deadlock

2020. 8. 3. 02:48Computer Science/Operating System

Deadlock

데드락 이란 예시 예제 머플러

  • '교착 상태'라고도 하며, 두 개 이상의 작업이 서로 상대방의 작업이 끝나기 만을 기다리고 있기 때문에 결과적으로 아무것도 완료되지 못하는 상태

  • 시스템적으로 한정된 자원을 여러 곳에서 사용하려고 할 때 발생

  • 데드락이 발생할 수 있는 경우:

    img

    Process 1과 Process2가 Resource 1, 2를 둘 다 얻어야 한다고 가정할 때, 서로 원하는 Resource가 상대 Process에게 할당되어 있기 때문에 두 프로세스가 무한정 기다리게 된다.



교착 상태의 조건

  • 한 시스템 내에서 다음의 네 가지 조건이 동시에 성립할 때 발생
  • 따라서, 아래의 네 가지 조건 중 하나라도 성립하지 않도록 만든다면 교착 상태 해결 가능
조건 설명
상호 배제
(Mutual exclusion)
- 자원은 한 번에 하나의 프로세스만이 사용할 수 있어야 한다.
- 프로세스들이 필요로 하는 자원에 대해 배타적인 통제권을 요구한다.
- 상호 배제를 제거하는 것은 가장 확실한 교착 상태 제거 방법이지만, 프로세스나 스레드의 동시성 제어 외에는 잘 사용하지 않는다. (Mutex)
점유 대기
(Hold and wait)
- 최소한 하나의 자원을 점유하고 있으면서 다른 프로세스에 할당되어 사용하고 있는 자원을 추가로 점유하기 위해 대기하는 프로세스가 있어야 한다.
- 프로세스가 할당된 자원을 가진 상태에서 다른 자원을 기다린다.
ex) Skype가 마이크와 카메라를 쓴다고 가정. 이 때, 마이크는 연결에 성공했지만 다른 앱이 카메라를 잡고 있어서 연결할 수 없는 경우, Skype가 카메라를 계속 대기하게 되므로 다른 앱이 마이크를 사용하지 못하는 상황
비선점
(No preemption)
- 다른 프로세스에 할당된 자원은 사용이 끝날 때까지 강제로 빼앗을 수 없어야 한다.
- 프로세스가 어떤 자원의 사용을 끝낼 때까지 그 자원을 뺏을 수 없다.
순환 대기
(Circular wait)
- 프로세스의 집합 {P0, P1, ... , Pn}에서 P0은 P1이 점유한 자원을 대기하고 P1은 P2가 점유한 자원을 대기하고 P2 ... Pn-1은 Pn이 점유한 자원을 대기하며 Pn은 P0가 점유한 자원을 요구해야 한다.
- 각 프로세스는 순환적으로 다음 프로세스가 요구하는 자원을 가지고 있다.
  • 이중 순환 대기 조건은 점유 대기 조건과 비선점 조건을 만족해야 성립하는 조건이므로, 위 4가지 조건이 서로 완전히 독립적인 것은 아니다.



Deadlock의 해결 방법

img

두 개의 프로세스가 하나의 자원을 얻기 위해 경쟁하는 상황.
(A) FCFS를 따를 때 (B) 두 개의 프로세스가 같은 자원에 동시에 락을 걸어 데드락이 발생 (C) 동시에 락이 걸렸을 때, 한 쪽을 풀어줌으로써 데드락 해결 가능 (D) 데드락을 예방할 수 있는 locking 메커니즘

 

예방(Prevention)

교착 상태가 발생되지 않도록 사전에 예방하는 방법. 네 가지 발생 조건 중 하나를 제거함으로써 해결하는 방법으로, 일반적으로 자원 사용 효율성이 떨어지고 비용이 많이 드는 단점이 있다.

부정 설명
상호 배제 (Mutual exclusion) 부정 - 여러 개의 프로세스가 공유 자원을 사용할 수 있도록 한다.
점유 대기 (Hold and wait) 부정 - 프로세스가 실행되기 전 필요한 모든 자원을 할당한다.
- 프로세스가 자원을 점유하지 않은 상태에서만 자원을 요청할 수 있도록 한다.
비선점 (No preemption) 부정 - 자원을 점유하고 있는 프로세스가 다른 자원을 요구할 때 요청한 자원을 사용 가능한지 검사하여 사용 가능하다면 점유하고 있는 자원을 반납하고, 요구한 자원을 사용하기 위해 기다리게 한다.
- 이미 할당된 자원에 대해서 선점권을 가지지 않는다.
순환 대기 (Circular wait) 부정 - 자원에 고유한 번호를 할당하고, 번호 순서대로 자원을 요구하도록 한다.
- 각 프로세스는 현재 점유 중인 자원의 고유 번호를 기준으로 앞이나 뒤 어느 한 방향으로만 자원을 요구한다.

 

회피(Avoidance)

교착 상태의 발생 가능성을 계속 검사해서 교착 상태 발생 가능성이 있다면 회피해버리는 방식. 회피를 위해 safe state와 unsafe state라는 개념이 사용된다. 이때, Unsafe state란 교착 상태 발생 가능성이 있는 state를 말한다. 프로세스가 자원을 요구할 때, 시스템이 자원을 할당한 후에도 안정 상태로 남아있는지를 사전에 검사한다. 안정 상태에 있으면 자원을 할당하고, 그렇지 않으면 다른 프로세스들이 자원을 해지할 때까지 대기한다.

  • 자원 할당 그래프 알고리즘 (Resource Allocation Graph Algorithm)
    : 프로세스가 새로 요구하는 자원에 claim edge를 추가하고, 해당 프로세스가 실제로 자원을 할당받으면 claim edge는 assignment edge로 바꾼다. P1과 P2 두 프로세스 중 한 프로세스가 실제로 R2를 할당받는다면, 그때부터는 교착 상태가 발생할 가능성이 생기기 때문에 unsafe state가 되며, 이 경우 자원을 할당하지 않는다.

  • 은행원 알고리즘 (Banker's Algorithm)
    : E. Djikstra가 제안한 방법으로, 은행에서 모든 고객의 요구가 충족되도록 현금을 할당하는 데서 유래한 기법. Safety Algorithm과 Resource Request Algorithm을 사용한다.

 

탐지 (Detection)

알고리즘을 통해 현재 시스템에 Deadlock이 있는지 찾고, 알고리즘을 통해 복구하는 것. 하지만 어느 시점에서 교착 상태를 탐지해야 하는지를 알 수 없으므로 주기적으로 알고리즘을 실행해야하며, 이에 대한 비용이 커서 실용적이지 못하다.

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

    img

    : 자원 할당에 대한 그래프를 구성한 후, 그래프에 사이클이 없을 때에만 자원을 할당한다. 프로세스 Pi로부터 자원 Rj로의 방향 간선은 Pi ->Rj로 표현하며 이것은 프로세스 Pi가 자원 Rj을 요청하는 것으로 현재 이 자원을 기다리는 상태이다. 자원 Rj로부터 프로세스 Pi로의 방향 간선은 Rj->Pi로 표현하며 이것은 자원이 프로세스 Pi에 이미 할당된 것을 의미 한다. 자원을 요청할 때마다 탐지 알고리즘을 실행하면 그에 대한 오버헤드가 발생한다. 프로세스가 하나의 자원만 사용하는 시스템에서 사용된다.

[참고] 자원 할당 그래프 알고리즘은 회피와 예방에서 모두 사용될 수 있다.

 

회복 (Recovery)

  • 교착 상태를 일으킨 프로세스를 종료하거나, 할당된 자원을 해제함으로써 회복하는 것
종류 방법
프로세스를 종료하는 방법 - 교착 상태의 프로세스를 모두 중지
- 교착 상태가 제거될 때까지 한 프로세스씩 중지
자원을 선점하는 방법 - 교착 상태의 프로세스가 점유하고 있는 자원을 선점하여 다른 프로세스에게 할당하며, 해당 프로세스는 일시 정지
- 우선 순위가 낮은 프로세스, 수행된 횟수가 적은 프로세스 등을 위주로 프로세스의 자원을 선점

 

무시 (Ignorance)

  • 교착상태 자체를 무시하고, 특별한 조치를 취하지 않는다. 교착상태의 발생 확률이 낮은 상황에서 효율적이다.

  • 만약 교착상태가 발생한다면, 프로세스를 종료하거나 자원을 선점하여 회복한다.

  • UNIX, Windows 등 대부분의 운영체제가 이 방법을 사용한다.



식사하는 철학자들 문제(Dining Philosophers)로 보는 Deadlock

img

다섯 명의 철학자가 원탁에 앉아 있고, 각자의 앞에는 스파게티가 있고 양옆에 포크가 하나씩 있다. 그리고 각각의 철학자는 다른 철학자에게 말을 할 수 없다. 이때 철학자가 스파게티를 먹기 위해서는 양 옆의 포크를 동시에 들어야 한다.

이때 각각의 철학자가 왼쪽의 포크를 들고 그 다음 오른쪽의 포크를 들어서 스파게티를 먹는 알고리즘을 가지고 있으면, 다섯 철학자는 동시에 왼쪽의 포크를 들 수 있으나 오른쪽의 포크는 이미 가져가진 상태이기 때문에 다섯 명 모두가 무한정 서로를 기다리는 교착 상태에 빠지게 될 수 있다. 이 상황에서 철학자들을 프로세스, 포크가 자원이라고 생각한다면 상호 배제-철학자들은 포크를 공유할 수 없다. / 점유 상태로 대기-자신의 왼쪽에 앉은 철학자가 포크를 놓을 때까지 기다린다. / 선점 불가-철학자들은 왼쪽 철학자의 포크를 빼앗을 수 없다. / 순환 대기-각 철학자들은 자신의 왼쪽 철학자의 포크를 대기한다. 라고 생각할 수 있다.

또한 어떤 경우에는 동시에 양쪽 포크를 집을 수 없어 식사를 하지 못하는 기아 상태가 발생할 수도 있고, 몇몇 철학자가 다른 철학자보다 식사를 적게 하는 경우가 발생하기도 한다.

이러한 교착 상태를 회피하려면 위에서 언급했듯이 교착 상태 발생 조건 4가지 중 한 가지만 해제하면 된다. 상호 배제와 선점 불가의 경우 문제의 조건 때문에 해소가 불가능하다. 점유 상태로 대기를 해소하려면 '왼쪽 포크를 집을 수 없을 때 오른쪽 포크를 식탁 위에 내려놓는 방법'이 있고, 순환 대기를 해소하려면 포크에 우선 순위를 매기는 방법이 있다.



추가

[1] 해결 방법 중에서 어떤 방식을 가장 많이 사용하는지?

대부분의 운영체제는 교착상태 발생을 무시한다. 실제로 처리하는 프로그램의 작성은 응용 개발자의 책임.

[2] 예방과 회피가 비슷한데, 어떻게 다른지?

예방은 네 가지 조건 중에 하나를 아예 불가능하도록 바꿔버리는 것이다. 예를 들어, 위의 식사하는 철학자 문제에서, 철학자끼리 포크를 공유할 수 없는 조건을 공유할 수 있도록 바꿔버린다면 상호 배제 부정을 한 것으로, 교착 상태가 발생할 조건이 애초부터 성립되지 않는다. 회피는 Deadlock의 발생 가능성을 계속 검사해서 발생 가능성에 따라 안정 상태와 불안정 상태로 나누고, 불안정 상태라면 Deadlock이 발생할 가능성이 있다고 판단하여 해당 작업을 피해버리는 것이다.