더북(TheBook)

마찬가지로 C → A 순서로 잠그는 것도 의 순서를 어겼으므로 교착 상태를 일으킵니다.

lock(C)
lock(A)
unlock(A)
unlock(C)

이번에는 좀 더 재미있는 것을 볼 텐데, 그 전에 알아 두어야 할 것이 하나 있습니다. 뮤텍스는 재귀성을 가지는 것과 가지지 않는 것이 있습니다. 재귀 뮤텍스(recursive mutex)는 한 스레드가 뮤텍스를 여러 번 반복해서 잠그는 것을 원활하게 처리해 줍니다.

이미 스레드 1이 뮤텍스 M의 lock() 함수를 호출해서 잠갔는데, 스레드 1이 또 lock(M)을 호출했다고 가정합시다. 재귀 뮤텍스는 스레드 1이 중복해서 잠그는 것을 이미 알고 있습니다. 따라서 내부적으로 단지 이렇게만 상태 업데이트를 합니다. “스레드 1이 나를 두 번 잠갔다.” 이 상태에서 스레드 1이 unlock(M)을 한 번만 호출하면 ‘두 번 잠금 → 한 번 잠금’으로 상태만 바뀔 뿐, 실질적인 잠금 해제는 일어나지 않습니다. 이 상태에서 한 번 더 unlock(M)을 호출해야 비로소 잠금 해제가 일어납니다.

lock(M)    // 잠금을 획득했다.
lock(M)    // 잠근 것을 또 잠갔다.
unlock(M)  // 잠금이 해제되었다. 그러나 아직 한 번 더 남았다.
unlock(M)  // 잠금이 해제되었다. 비로소 잠금 해제가 실질적으로 된다.

우리는 여기서 재귀 뮤텍스만 다루겠습니다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.