<aside>
📚 http://www.yes24.com/Product/Goods/71768958 를 읽고 간단하게 정리한 내용입니다.
</aside>
정의
- 멀티 스레드 환경에서 두 스레드가 서로의 수행 종료를 기다리는 상황
- 스레드 A가 스레드 B가 하던 일을 끝내기를 기다리고 있는데 스레드 B는 스레드 A가 하던 일을 끝내기를 기다리고 있어서 결과적으로 어느 스레드도 수행을 완료하지 못하고 있는 상황
왜 발생하는가?
복수의 뮤텍스끼리의 충돌
뮤텍스(Mutex)란?
- Mutual Exclusion. 상호배제.
- 멀티 스레드 환경 → 복수의 스레드가 병렬적으로 작업을 수행 → 하나 이상의 스레드가 공동 자원에 접근해서 그 데이터의 상태를 예측할 수 없게 되는 상황이 발생 (경쟁상태, Race Condition)
- 예를 들어,
a
라는 변수에 대해 스레드 A가 a + 5
와 a * 10
을 잇달아 수행하고 이 결과값을 스레드 B가 가져와서 a + 10
을 수행하는 경우, 그 결과가 반드시 (a + 5) * 10 + 10
이라는 보장이 없다 → 컨택스트 스위칭이 랜덤하게 일어나기 때문
- 여러 스레드의 작업을 번갈아 수행하기 위해 CPU가 한 스레드의 작업 결과를 잠시 저장해놓고 다른 스레드로 넘어가는 컨택스트 스위칭은 기계어 단위로 수행됨. 즉, 하나의 명령을 수행하는 도중에 컨택스트 스위칭이 일어나는 게 아니라 반드시 하나의 명령을 다 마친 후에 일어나게 됨.
- 이 때, 코드가 기계어로 컴파일 되는 과정에서 한 줄의 코드가 반드시 하나의 명령어로 변환되지는 않음 → 코드가 몇 줄의 기계어로 변환될지 예측할 수 없기 때문에 컨택스트 스위칭이 일어나는 시점을 정확히 파악할 수 없음 → 경쟁상태 발생
- 즉, 뮤텍스란 임계영역(Critical Section)에서의 경쟁상태(Race Condition)를 해결하기 위한 방법
- 임계영역이란 여러 스레드가 공통 자원에 접근하게 되는 부분 → 위 예시에서 a에 대한 연산 코드
- 하나의 스레드가 자원에 접근하는 동안 다른 스레드가 자원에 접근할 수 없게 잠가버리고, 수행이 끝나면 잠금을 해제하는 방식
- lock()을 통해 뮤텍스에 대한 사용권을 획득하고, unlock()을 통해 뮤텍스를 반납 → 뮤텍스 == 열쇠
뮤텍스가 교착상태와 어떻게 연관되는가?
여러 뮤텍스의 잠금 순서가 꼬일 때 교착상태가 발생한다. <<
멀티 스레드 사용 시, 여러 뮤텍스가 생기고 여러 스레드가 각각의 뮤텍스를 사용해야 하는데, 특정 뮤텍스에 대한 잠금이 풀리지 않으면 그 자원을 필요로 하는 스레드들의 작업이 완료되지 못하고 교착상태에 빠짐
→ 예를 들어 스레드 A가 뮤텍스 A를 잠갔다가 반납하고 뮤텍스 B를 사용하려 하고 스레드 B는 뮤텍스 B를 잠갔다가 반납한 후 뮤텍스 A를 사용하려는 경우, 뮤텍스 A, B의 잠금 순서가 어긋나면 스레드 A와 스레드 B는 필요한 뮤텍스를 얻지 못하게 되므로 영원히 작업을 끝마치지 못하게 됨