안녕하세요,
재재입니다.
지난 포스팅에서는 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 들과 같이 주의해야하는 내용이 몇개 있습니다.
- deadlock 문제 – lock의 순서에 따라 스레드들이 무한 대기상태에 빠질 수 있음
- starvation 문제 – 지속적인 읽기 작업 때문에 쓰기 작업이 무한대기상태에 빠질 수 있음
shared_mutex를 사용할 때는 이러한 주의사항을 고려하여 적절한 락 관리를 해야 합니다.
(5) 결론
c++ shared_mutex 는 특정 상황에서 효과적인 동기화 도구로 사용될 수 있습니다.
하지만 다른 mutex 처럼, 올바르게 사용되어야합니다.
사용 전에 요구 사항을 정확히 파악하고,
용도에 적절한 동기화 도구 (mutex) 를 선택하는 것이 좋습니다.