프로그래밍/시스템
Deadlock(교착 상태) - 4. 실제 사례로 보는 데드락
개발_노트
2025. 3. 25. 22:51
4. 실제 사례로 보는 데드락
데드락(교착 상태)은 이론에서만 다뤄지는 문제가 아닙니다.
운영체제, 데이터베이스, 멀티스레드 프로그래밍, 분산 시스템 등 다양한 실무 환경에서 실제로 발생하며,
시스템 정지나 성능 저하의 직접적인 원인이 됩니다. 아래에 환경별 사례를 정리합니다.
✅ 운영체제에서의 데드락
● 파일과 프린터 자원 충돌
- 프로세스 A는 파일을 점유한 후 프린터를 요청
- 프로세스 B는 프린터를 점유한 후 파일을 요청
- 서로가 필요한 자원을 상대가 점유하고 있어, 무한 대기 상태 발생 → 데드락
● 시스템 콜 간 커널 락 충돌
- 두 커널 스레드가 read()와 write() 시스템 콜을 처리 중
- 락 획득 순서가 어긋나면서 커널 내부에서 데드락 발생 가능성 존재
✅ 데이터베이스 트랜잭션 충돌 사례
● 교차 테이블 접근
- 트랜잭션 A: 테이블 X의 행을 점유한 후 테이블 Y 접근 시도
- 트랜잭션 B: 테이블 Y의 행을 점유한 후 테이블 X 접근 시도
- 교차 잠금 발생 → 트랜잭션 간 순환 대기 → 데드락
● 외부 I/O 대기 포함 트랜잭션
- 트랜잭션이 자원을 점유한 상태로 외부 API 응답을 기다리는 동안,
다른 트랜잭션이 해당 자원을 요청하며 시스템 전체가 교착 상태에 빠질 수 있음
※ 주요 RDBMS는 데드락을 감지하여 자동으로 트랜잭션을 강제 종료(rollback)함
✅ 멀티스레드 환경에서의 데드락
● 락 순서 충돌
- 스레드 A: 락 X → 락 Y 순서로 획득
- 스레드 B: 락 Y → 락 X 순서로 획득
- 서로가 상대방이 점유한 락을 기다리며 무한 대기 상태 → 데드락
● 잘못된 재귀 락 사용
- 스레드가 자신이 이미 점유한 락을 중첩 요청하거나,
락 해제를 누락한 경우 교착 상태가 발생할 수 있음
✅ 분산 시스템에서의 데드락 (심화)
분산 시스템, 특히 마이크로서비스 아키텍처에서는
서비스 간의 호출 흐름과 분산된 자원 점유가 맞물리며 복잡한 형태의 데드락이 발생할 수 있습니다.
● 서비스 간 순환 호출 + 자원 점유
- 서비스 A는 데이터베이스 락을 점유한 상태로 서비스 B 호출
- 서비스 B는 Redis 락을 점유한 상태로 서비스 C 호출
- 서비스 C는 다시 A를 호출 → 순환 호출 구조 + 자원 점유 상태 → 분산 데드락 발생
● 증상은 있으나 오류는 없음
- 표면적으로는 단순한 응답 지연이나 타임아웃 현상처럼 보이지만,
실제로는 서비스 간 순환 대기로 인해 전체 처리가 중단되는 상황 - 일반적인 데드락 탐지 도구로는 식별이 어려움 → 분산 트레이싱 및 호출 경로 분석 필요
📝 요약 정리
환경 | 데드락 주요 원인 | 대응 전략 예시 |
운영체제 | 자원 요청 순서 충돌 | 자원 요청 순서 통일, 커널 락 최소화 |
데이터베이스 | 레코드 락 교차 점유 | 트랜잭션 구조 개선, 타임아웃 설정 |
멀티스레드 | 락 획득 순서 불일치 | 락 순서 고정, 재귀 락 사용 주의 |
분산 시스템 | 서비스 간 순환 호출 + 락 점유 | 서비스 설계 정비, 락 최소화, 트레이싱 도입 |
데드락은 시스템의 규모와 복잡도가 커질수록 더 다양한 형태로 발생하며,
구조적인 설계와 자원 관리 전략 없이는 쉽게 발견되거나 해결되지 않습니다.
사례를 통해 데드락의 실전 위협을 정확히 이해하고, 사전 예방이 가능한 시스템을 설계해야 합니다.