제목: “이번 주의 팁 #197: Reader Lock은 드물게 사용해야 합니다”

원문 게시일: 2021년 7월 29일
업데이트: 2024년 4월 1일

작성자: Titus Winters

빠른 링크: abseil.io/tips/197


Reader Lock이란?

absl::Mutex 클래스는 두 가지 잠금 방식을 지원합니다:

  1. 배타적 잠금 (Exclusive Lock): 한 번에 하나의 스레드만 잠금을 가질 수 있습니다.
  2. 공유 잠금 (Shared Lock): 두 가지 모드로 작동합니다.
    • 쓰기 모드: 배타적 잠금을 사용합니다.
    • 읽기 모드: 여러 스레드가 동시에 잠금을 가질 수 있습니다.

공유 잠금이 유용한 이유는 여러 스레드가 데이터에 대해 읽기 전용 작업을 수행할 때 경쟁 상태를 줄이고 동기화 문제를 방지할 수 있기 때문입니다.

absl::MutexMutex::Lock()(또는 동일한 동작을 하는 Mutex::WriterLock())과 Mutex::ReaderLock()을 제공합니다. 이를 보면, 데이터를 읽기만 하는 경우에는 ReaderLock()을 사용하는 것이 더 나아 보일 수 있습니다. 하지만 대부분의 경우, 이는 잘못된 선택입니다.


Reader Lock의 문제점

1. Reader Lock은 느리다

ReaderLock()은 배타적 잠금보다 더 많은 부가 작업과 오버헤드를 요구합니다.
결과적으로, **짧은 임계 구역(critical section)**에서는 공유 잠금을 사용하는 것이 오히려 성능을 저하시키는 경우가 많습니다. 경쟁 상태가 없는 경우에는 공유 잠금의 이점도 크게 줄어듭니다.

배타적 잠금과 공유 잠금의 차이점:

이로 인해 공유 잠금은 더 복잡하며, 경쟁 상태가 발생할 경우 성능 저하가 심해질 수 있습니다.


2. 언제 공유 잠금이 유용한가?

공유 잠금은 잠금을 오래 유지해야 하며 여러 스레드가 동시에 공유 잠금을 사용할 가능성이 높을 때 유용합니다.
예를 들어, 큰 컨테이너를 반복 처리하거나 복잡한 계산이 필요한 경우 공유 잠금이 적합할 수 있습니다.

그러나 잠금을 짧게 유지하는 단순 조회의 경우, 공유 잠금은 추가적인 복잡성과 비용을 초래합니다.

CPP
// 나쁜 예제: 짧은 임계 구역에서 Reader Lock 사용
int Foo::GetElementSize() const {
  absl::ReaderMutexLock l(&lock_);
  return element_size_;
}
클릭하여 더 보기

위 코드는 element_size_ 값을 단순히 조회하기 위해 공유 잠금을 사용합니다.
그러나 잠금 관리의 부가 비용이 실제 데이터 접근보다 크기 때문에 성능이 떨어질 수 있습니다.


3. 대안적인 접근법

공유 잠금이 유용한 경우에도, 경쟁 상태를 완전히 피하는 더 나은 방법을 종종 찾을 수 있습니다.
예를 들어:


올바른 접근법

1. Reader Lock 사용을 주의 깊게 검토하라

코드에서 ReaderLock()을 발견하거나 새로 작성하려는 경우, **“이 잠금이 오래 유지될 가능성이 있는가?”**라는 질문을 던져야 합니다.


2. 성능 분석 활용

Reader Lock의 유효성은 상황에 따라 달라질 수 있습니다.
프로파일링 도구를 사용하여 경쟁 상태와 잠금 유지 시간을 측정하고, Reader Lock이 실제로 성능에 기여하는지 확인해야 합니다.


결론

ReaderLock()은 특정 상황에서 유용할 수 있지만, 대부분의 경우 배타적 잠금이 더 적합합니다.
특히 짧은 임계 구역에서는 Reader Lock의 복잡성과 비용이 실제 이점보다 클 가능성이 큽니다.

Reader Lock을 사용하기 전에 경쟁 상태, 임계 구역 길이, 잠금 유지 시간을 평가하고, 가능한 경우 RCU나 다른 비동기화 기법을 고려하세요.

라이선스

저작자: Jaehun Ryu

링크: https://jaehun.me/posts/abseil-tip-197-reader-lock%EC%9D%80-%EB%93%9C%EB%AC%BC%EA%B2%8C-%EC%82%AC%EC%9A%A9%ED%95%B4%EC%95%BC-%ED%95%A9%EB%8B%88%EB%8B%A4/

라이선스: CC BY 4.0

이 저작물은 크리에이티브 커먼즈 저작자표시 4.0 국제 라이선스에 따라 이용할 수 있습니다. 출처를 밝히면 상업적 목적을 포함해 자유롭게 이용 가능합니다.

댓글

검색 시작

검색어를 입력하세요

↑↓
ESC
⌘K 단축키