번 (Deadlock 분석) - 필수 개념
1. 멀티스레드 (Multithreading)
정의: 하나의 프로세스 내에서 여러 개의 스레드가 동시에 실행되는 것
프로세스 vs 스레드:
프로세스 (Process):
- 독립적인 프로그램 실행 단위
- 각자 메모리 공간 보유
- 예: 크롬, 유튜브, 카톡 앱
스레드 (Thread):
- 같은 프로세스 내의 실행 단위
- 메모리 공간 공유
- 예: 크롬 내의 여러 탭들이 동시에 작동
우리 테스트:
agent-leak-app 프로세스 내에
├─ Worker-Thread-1
├─ Worker-Thread-2
└─ (다른 스레드들)
이 동시에 실행2. 자원 (Resource)
정의: 여러 스레드가 공유하는 데이터나 객체
우리 테스트의 자원:
1. Shared_Memory_A (공유 메모리)
2. Socket_Pool_B (소켓 풀)
이 둘을 여러 스레드가 동시에 접근하려 함현실적 예시:
은행의 계좌 잔액 (자원):
- 스레드1: 입금 시도
- 스레드2: 출금 시도
→ 동시에 접근하면 일관성 깨짐
→ 따라서 한 번에 1개 스레드만 접근 가능3. 락 (Lock / Mutual Exclusion - 상호 배제)
정의: 한 번에 1개 스레드만 자원을 사용하도록 제한하는 메커니즘
동작:
Lock 획득:
스레드1: "Shared_Memory_A 사용하겠습니다" (Lock 획득 ✓)
스레드2: "Shared_Memory_A 사용하겠습니다" (Lock 대기... ⏳)
스레드1이 작업 완료:
스레드1: "다 했습니다" (Lock 해제)
스레드2: "이제 사용합니다" (Lock 획득 ✓)우리 로그에서:
2026-05-27 05:50:08,816 [INFO] LOCK ACQUIRED: [Shared_Memory_A]
→ 이 스레드가 락을 획득함
→ 다른 스레드는 접근 불가4. 교착상태 (Deadlock)
정의: 2개 이상의 스레드가 서로가 가진 자원을 기다리며 무한히 대기하는 상태
우리 테스트의 상황:
시간순서:
T1: 스레드1이 자원A 획득
스레드2가 자원B 획득
T2: 스레드1이 자원B 필요 → 스레드2가 가지고 있음 → 대기
스레드2가 자원A 필요 → 스레드1이 가지고 있음 → 대기
T3: 둘 다 자신이 필요한 자원을 못 가지고 있음
→ 영원히 대기 (교착상태)
로그:
2026-05-27 05:50:10,820 [INFO] WAITING for [Socket_Pool_B]... (Status: BLOCKED)
2026-05-27 05:50:10,820 [INFO] WAITING for [Shared_Memory_A]... (Status: BLOCKED)
→ 둘 다 BLOCKED 상태에서 멈춤현실적 예시:
교과서의 "식사하는 철학자 문제":
철학자 A, B가 앉아있고 포크 2개가 있음
(A 왼쪽에 포크1, 오른쪽에 포크2, B 오른쪽에 포크1... 등)
A: 왼쪽 포크 집음 (포크1 획득)
B: 오른쪽 포크 집음 (포크2 획득)
A: 오른쪽 포크 필요 → B가 가지고 있음 (대기)
B: 왼쪽 포크 필요 → A가 가지고 있음 (대기)
→ 둘 다 영원히 기다림 (밥을 못 먹음)5. 데드락 4가지 필수 조건 (Deadlock Conditions)
데드락이 발생하려면 다음 4가지 조건을 모두 만족해야 함:
조건 1: 상호 배제 (Mutual Exclusion)
자원이 배타적으로 사용됨
= 한 번에 1개 스레드만 사용 가능
우리 경우:
Shared_Memory_A는 한 번에 1개 스레드만 접근 가능
Socket_Pool_B도 한 번에 1개 스레드만 접근 가능
✓ 만족조건 2: 점유 대기 (Hold and Wait)
스레드가 자원을 보유하면서 다른 자원 대기
= 가진 것 놓지 않고 필요한 것 기다림
우리 경우:
스레드1: 자원A 보유 → 자원B 대기
스레드2: 자원B 보유 → 자원A 대기
✓ 만족조건 3: 비선점 (No Preemption)
자원을 강제로 빼앗을 수 없음
= 획득한 스레드만 해제 가능
우리 경우:
스레드1이 자원A를 가지면
다른 스레드가 강제로 빼앗을 수 없음
(스레드1이 해제할 때까지 대기)
✓ 만족조건 4: 순환 대기 (Circular Wait)
자원 대기가 순환 구조를 이룸
= A → B → A 형태 (또는 A → B → C → A 등)
우리 경우:
스레드1 (자원A 보유) → 스레드2 (자원B 보유) → 스레드1
↑ ↓
└──────────────────────────────┘
순환 구조!
✓ 만족결론: 4가지 조건 모두 만족 → 데드락 발생
6. 자원 획득 순서 (Resource Ordering)
정의: 여러 자원을 사용할 때 획득하는 순서
문제 상황 (우리 테스트):
스레드1: 자원A → 자원B 순서로 획득
스레드2: 자원B → 자원A 순서로 획득
↑
다른 순서!해결책:
모든 스레드가 동일 순서로 획득:
방법1:
스레드1: 자원A → 자원B
스레드2: 자원A → 자원B (동일 순서)
방법2:
스레드1: 자원B → 자원A
스레드2: 자원B → 자원A (동일 순서)
→ 순환 대기 불가능!7. 블로킹 (Blocking) vs 대기 (Waiting)
블로킹 (Blocking):
스레드가 자원을 기다리며 실행을 멈춤
로그에서:
[INFO] WAITING for [Socket_Pool_B]... (Status: BLOCKED)
→ BLOCKED 상태 = 실행하지 않음, 기다리는 중CPU/메모리 상태:
BLOCKED 상태의 스레드:
- CPU: 0% (실행하지 않음)
- 메모리: 변화 없음 (새로 할당 안 함)
- 로그: 안 나옴 (I/O 수행 안 함)우리 테스트 결과:
2026-05-27 05:50:10,820 이후:
- CPU: 0%
- 메모리: 정체
- 로그: 없음
→ 모든 스레드가 BLOCKED 상태출처: Codyssey-B1/B4-2