안녕하세요,
재재입니다.

지난 포스팅에서는 c++ recursive_mutex 를 다뤘었는데요.

이번 포스팅에서는,
c++ shared_mutex 활용하는 방법을 자세히 설명드릴게요.

(1) c++ std::shared_mutex 란 ?

c++ std::shared_mutex 는 c++17에서 처음 도입되었습니다.

여러 스레드가 동시에 읽기 작업을 수행하면서,
단일 스레드에서만 쓰기 작업을 수행할 때 사용할 수 있도록 의도되었습니다.

다시 말해 데이터에 접근해서 동시 읽기를 가능하게 하고,
반면 데이터 쓰기 작업은 하나의 스레드만 수행 할 수 있도록 합니다.

https://en.cppreference.com/w/cpp/thread/shared_mutex

(2) std::shared_mutex 사용 시기

c++ std::shared_mutex 는 데이터를 자주 읽고,
간헐적으로 쓰기를 수행할 때 효과적입니다.

읽기 작업이 쓰기 작업보다 상대적으로 많은 빈도를 갖는다면,
일반적인 상황에서 사용하는 뮤텍스 (std::mutex) 보다 성능이 좋습니다.

다시 말해,
동시에 여러 스레드가 동일한 데이터를 읽는 상황에서,
동기화 비용을 최소화하고 싶을 때 사용합니다.

(3) c++ shared_mutex 활용

아래 두가지 예제 코드를 준비했습니다.

1. 예제 코드 – 데이터 쓰기

쓰기 작업을 수행하기 위해 unique_lock 을 사용합니다.
다른 스레드는 해당 데이터의 읽기 또는 쓰기를 수행할 수 없습니다.

class DataThread {
...
void Write(int value) {
    std::unique_lock lock(shared_mtex);
    this->cur_value = value;
}
private:
    std::shared_mutex shared_mtex;
    int cur_value = 0;
};

2. 예제 코드 – 데이터 읽기

읽기 작업을 수행하기 위해 shared lock을 획득하는 코드입니다.

#include <cstdio>
class DataThread {
...
void ReadAndPrint() {
    std::shared_lock lock(shared_mtex);
    printf("%d\n", this->cur_value);
}
private:
    std::shared_mutex shared_mtex;
    int cur_value = 0;
};

(4) 주의사항

std::shared_mutex 도 다른 mutex 들과 같이 주의해야하는 내용이 몇개 있습니다.

  1.  deadlock 문제 – lock의 순서에 따라 스레드들이 무한 대기상태에 빠질 수 있음
  2.  starvation 문제 – 지속적인 읽기 작업 때문에 쓰기 작업이 무한대기상태에 빠질 수 있음

shared_mutex를 사용할 때는 이러한 주의사항을 고려하여 적절한 락 관리를 해야 합니다.

(5) 결론

c++ shared_mutex 는 특정 상황에서 효과적인 동기화 도구로 사용될 수 있습니다.
하지만 다른 mutex 처럼, 올바르게 사용되어야합니다.
사용 전에 요구 사항을 정확히 파악하고,
용도에 적절한 동기화 도구 (mutex) 를 선택하는 것이 좋습니다.

c++ shared_mutex 활용하기
태그:                 

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다