제목: “이번 주의 팁 #197: Reader Lock은 드물게 사용해야 합니다”
원문 게시일: 2021년 7월 29일
업데이트: 2024년 4월 1일
작성자: Titus Winters
빠른 링크: abseil.io/tips/197
Reader Lock이란?
absl::Mutex
클래스는 두 가지 잠금 방식을 지원합니다:
- 배타적 잠금 (Exclusive Lock): 한 번에 하나의 스레드만 잠금을 가질 수 있습니다.
- 공유 잠금 (Shared Lock): 두 가지 모드로 작동합니다.
- 쓰기 모드: 배타적 잠금을 사용합니다.
- 읽기 모드: 여러 스레드가 동시에 잠금을 가질 수 있습니다.
공유 잠금이 유용한 이유는 여러 스레드가 데이터에 대해 읽기 전용 작업을 수행할 때 경쟁 상태를 줄이고 동기화 문제를 방지할 수 있기 때문입니다.
absl::Mutex
는 Mutex::Lock()
(또는 동일한 동작을 하는 Mutex::WriterLock()
)과 Mutex::ReaderLock()
을 제공합니다. 이를 보면, 데이터를 읽기만 하는 경우에는 ReaderLock()
을 사용하는 것이 더 나아 보일 수 있습니다. 하지만 대부분의 경우, 이는 잘못된 선택입니다.
Reader Lock의 문제점
1. Reader Lock은 느리다
ReaderLock()
은 배타적 잠금보다 더 많은 부가 작업과 오버헤드를 요구합니다.
결과적으로, **짧은 임계 구역(critical section)**에서는 공유 잠금을 사용하는 것이 오히려 성능을 저하시키는 경우가 많습니다. 경쟁 상태가 없는 경우에는 공유 잠금의 이점도 크게 줄어듭니다.
배타적 잠금과 공유 잠금의 차이점:
- 배타적 잠금은 단순히 하나의 스레드만 접근 가능하도록 보장합니다.
- 공유 잠금은 읽기-쓰기 모드를 구분하며, 다른 스레드의 읽기/쓰기 상태를 확인하고 관리해야 합니다.
이로 인해 공유 잠금은 더 복잡하며, 경쟁 상태가 발생할 경우 성능 저하가 심해질 수 있습니다.
2. 언제 공유 잠금이 유용한가?
공유 잠금은 잠금을 오래 유지해야 하며 여러 스레드가 동시에 공유 잠금을 사용할 가능성이 높을 때 유용합니다.
예를 들어, 큰 컨테이너를 반복 처리하거나 복잡한 계산이 필요한 경우 공유 잠금이 적합할 수 있습니다.
그러나 잠금을 짧게 유지하는 단순 조회의 경우, 공유 잠금은 추가적인 복잡성과 비용을 초래합니다.
// 나쁜 예제: 짧은 임계 구역에서 Reader Lock 사용
int Foo::GetElementSize() const {
absl::ReaderMutexLock l(&lock_);
return element_size_;
}
위 코드는 element_size_
값을 단순히 조회하기 위해 공유 잠금을 사용합니다.
그러나 잠금 관리의 부가 비용이 실제 데이터 접근보다 크기 때문에 성능이 떨어질 수 있습니다.
3. 대안적인 접근법
공유 잠금이 유용한 경우에도, 경쟁 상태를 완전히 피하는 더 나은 방법을 종종 찾을 수 있습니다.
예를 들어:
- RCU(Read-Copy-Update) 방식은 읽기 경로를 사실상 무료로 만듭니다.
- 빠른 조회를 위해 동기화 자체를 줄이는 특수화된 인터페이스를 사용할 수 있습니다.
올바른 접근법
1. Reader Lock 사용을 주의 깊게 검토하라
코드에서 ReaderLock()
을 발견하거나 새로 작성하려는 경우, **“이 잠금이 오래 유지될 가능성이 있는가?”**라는 질문을 던져야 합니다.
- 단순 조회라면, 배타적 잠금(
Lock
)이 더 나은 선택일 가능성이 높습니다.
2. 성능 분석 활용
Reader Lock의 유효성은 상황에 따라 달라질 수 있습니다.
프로파일링 도구를 사용하여 경쟁 상태와 잠금 유지 시간을 측정하고, Reader Lock이 실제로 성능에 기여하는지 확인해야 합니다.
결론
ReaderLock()
은 특정 상황에서 유용할 수 있지만, 대부분의 경우 배타적 잠금이 더 적합합니다.
특히 짧은 임계 구역에서는 Reader Lock의 복잡성과 비용이 실제 이점보다 클 가능성이 큽니다.
Reader Lock을 사용하기 전에 경쟁 상태, 임계 구역 길이, 잠금 유지 시간을 평가하고, 가능한 경우 RCU나 다른 비동기화 기법을 고려하세요.
댓글