![]() |
---|
[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 발생 가능성이 있다. |