스레드 1이 ➋에서 뮤텍스 사용권을 얻는 데 성공하면 ➌으로 넘어갑니다. 그러나 ➋를 하려고 했더니 이미 다른 스레드 2가 ➋의 사용권을 얻은 상태라, 스레드 1은 더 이상 진행하지 못하고 그 자리에서 정지합니다.
한편 스레드 2에서 실행은 ➌을 넘어 ➍로 넘어갑니다. 스레드 2에서 실행 지점이 ➍를 통과하면 그제서야 스레드 1은 뮤텍스에 대한 사용권을 얻어 실행 지점이 ➌으로 넘어갑니다.
➌의 전후 부분인 lock()을 한 직후부터 unlock()을 하는 직전까지 구간 동안 x, y는 동시에 한 스레드로만 액세스가 보장됩니다.
뮤텍스는 다른 말로 임계 영역(critical section)이라고도 합니다.7 멀티스레드 프로그래밍에서 뮤텍스에 대한 사용권을 얻는 과정은 ‘잠근다(lock)’고도 표현합니다. 물론 그 반대는 잠금 해제(unlock)가 되겠지요. 흔히 “OO를 잠근다.”라고 하면 OO를 보호하는 뮤텍스에 대해 잠금을 한다는 뜻으로 해석하면 됩니다. 앞 예제의 경우 mx.lock()은 “x, y를 잠근다.”라고 표현할 수 있습니다.
그런데 매번 lock()과 unlock()을 호출하는 것은 번거로울 뿐만 아니라 예외 처리 코드 작성도 어렵습니다. 다음을 볼까요?
코드 lock, unlock을 명시적으로 호출
std::mutex mx; // ➊ mx.lock(); // ➋ read(x); // ➌ write(y); // ➍ sum(x); // ➎ mx.unlock(); // ➏
7 윈도에서는 뮤텍스보다 임계 영역이 처리 속도가 빨라 임계 영역 사용을 권장하는 편입니다. 리눅스에는 뮤텍스밖에 없지만, 뮤텍스는 임계 영역과 같은 방식으로 작동할 수 있도록 최적화되어 있습니다. 윈도의 임계 영역은 리눅스에서 이름 없는(unnamed) 뮤텍스에 해당합니다.