![]() |
|---|
| [Deadlock 발생 상황] |
| 1. A, semWait(s1) 실행 |
| 2. B, semWait(s2) 실행 |
| 3. B, semWait(s1) 실행 -> B, Blocekd |
| 4. A, semWait(s2) 실행 -> A, Blocked |
| - A의 Blocked 상태를 해제할 수 있는 프로세스 = B |
| - B의 Blocked 상태를 해제할 수 있는 프로세스 = A |
| - A, B 둘 다 Blocked 상태 -> Deadlock 발생 |
| - semSignal() 코드를 다른 프로세스가 실행할 수 있다면 Deadlock이 발생하지 않을 수 있다. |
💡 아래의 4가지 조건 모두 만족해야 Deadlock 이 발생한다.
![]() | ![]() |
|---|
주로 Deadlock은 두 프로세스 사이에서 발생한다.
- Deadlock에 걸린 두 프로세스가 가지고 있는 자원을 요청하는 프로세스 -> Blocked
- Blocked 상태의 프로세스가 가지고 있는 자원을 요청하는 프로세스 -> Blocked
- 연쇄적으로 프로세스가 Blocked 상태가 되는 상황이 발생할 수 있다.
증명
전제: P1, R1 소유 & R2 요청 / P2, R1 요청 & R2 소유
P1 입장, R1# < R2#
P2 입장, R1# > R2#
두 프로세스의 입장이 동시에 성립 불가능 -> 사이클 X -> Deadlock 발생 X
![]() |
|---|
| C - A의 각 행을 V와 비교했을 때 자원 할당 후 종료 가능한 프로세스는 P2이다. |
↓
![]() |
|---|
| P2의 종료 가정 -> V += A[P2] = {6,2,3} / C-A[P2] = {0,0,0} |
| C-A의 각 행을 V와 비교했을 때 모든 프로세스의 종료가 가능하다. -> 프로세스 번호 순서대로 종료한다. |
| P1의 종료 가정 -> V += A[P1] = {7,2,3} |
| P3의 종료 가정 -> V += A[P3] = {9,3,4} |
| P4의 종료 가정 -> V += A[P4] = {9,3,6} |
| 모든 프로세스의 종료가 가능하므로 자원 할당 전의 처음 상태는 Safe 상태이다. |
![]() |
|---|
| P1이 R1과 R3을 하나씩 추가적으로 요청했을 때 할당한 것을 가정한 상황이다. |
| C-A의 각 행을 V와 비교했을 때 어떠한 프로세스도 종료가 불가능 하므로 Unsafe 상태이다. |
| 자원 할당을 거절하고 이전 상태로 복구한다. |
![]() |
|---|
![]() |
|---|
| - rest: 프로세스 집합 |
| - currentavail: available 의 복사본 (원상태를 복구하기 위해) |
| - 종료 가능한 프로세스 탐색 과정을 모두 마친 후에 rest 집합이 비어 있다면 Safe 상태이고, 그렇지 않다면 Unsafe 상태이다. |
- 알고리즘 수행 후에 un-mark 상태의 프로세스가 남아 있다면 Deadlock이 발생한 것이다.
- un-mark 상태로 남아 있는 프로세스는 0개이거나 2개 이상이다. 1개일 수는 없다.

![]() |
|---|
| [문제 발생 Solution] |
| - P0~P4 모두 왼쪽 포크만 잡고 타임 아웃이 되는 경우, 오른쪽 포크 잡기를 시도할 때 모든 프로세스가 Blocked 되면서 Deadlock이 발생한다. |
| - 포크를 잡고 놓는 순서를 바꾼다고 Deadlock이 발생하지 않는 것은 아니다. |
![]() |
|---|
| [Real Solution] |
| - room에는 4개의 프로세스만이 진입할 수 있다. |
| - 따라서 하나의 프로세스는 반드시 두 포크 모두 사용 가능하므로 Deadlock이 발생하지 않는다. |
| - signal(room) 코드가 signal(fork) 코드 앞에 위치해도 Deadlock은 발생하지 않는다. |
Circular wait prevent 방식을 이용한 Deadlock prevent
A solution using a monitor
![]() |
|---|
| - fork: true(사용 가능), false(사용 중) |
| - 잡으려는 fork 값이 false 이면 모니터 내의 컨디션 변수에서 대기한다. |
| - 컨디션 변수의 개수 = fork 개수 |
| - 왼쪽 fork 잡는 데에 성공한 철학자는 오른쪽 fork 점유 여부를 확인하는 작업을 마칠 때까지 모니터를 떠나지 않기 때문에 deadlock 이 발생하지 않는다. |
| - get_forks()를 왼쪽, 오른쪽 포크를 잡는 함수로 분리할 경우, Deadlock 발생 가능성이 있다. |