At a Glance
text
mutual exclusion
+ hold and wait
+ no forced preemption
+ circular wait
= deadlock can occur네 조건 중 하나를 구조적으로 깨는 것이 예방의 핵심입니다. 실무에서는 모든 lock의 획득 순서를 고정하고 lock을 잡은 채 외부 호출을 하지 않는 규칙이 가장 직접적입니다.
대표 순환
text
Thread A: lock X -> waits for Y
Thread B: lock Y -> waits for X두 thread 모두 실행 중이 아니라 wait 상태여서 CPU 사용률이 낮은데도 프로그램이 멈춘 것처럼 보일 수 있습니다. Thread dump나 debugger에서 각 wait object와 owner를 따라가 wait-for cycle을 찾습니다.
예방 기준
- 여러 lock은 전역 순서로만 획득합니다.
- 필요 없는 중첩 lock을 줄이고 상태 owner를 단순화합니다.
- Lock 안에서 callback, logging sink, blocking I/O를 호출하지 않습니다.
- 여러 lock을 함께 얻는 표준 API가 있으면 사용합니다.
- RAII와
finally로 모든 예외·조기 반환 경로에서 해제합니다.
Timeout은 무한 대기를 감지하고 복구할 기회를 주지만 공유 상태를 자동으로 일관되게 만들지는 않습니다. Timeout 후 어떤 작업을 취소하거나 재시도할지 별도 정책이 필요합니다.
자주 틀리는 점
- race condition과 deadlock을 같은 오류로 보지 않습니다.
- 한 thread가 자기 자신이 보유한 non-recursive lock을 다시 얻는 경우도 deadlock이 될 수 있습니다.
- CPU 100%의 무한 spin은 deadlock과 증상이 다를 수 있습니다.
- 감시 thread가 lock을 강제로 해제하는 방식을 일반 해법으로 두지 않습니다.
참고 링크
1 sources