std::lock_guard / std::unique_lock / std::shared_lock

박성빈·2024년 12월 30일
0

Cpp

목록 보기
4/5

C++ 표준에서 사용되는 세 가지 락 관리 객체(std::lock_guard / std::unique_lock / std::shared_lock)에 대해 살펴보고 언제 무엇을 써야 하는지 학습한다.


std::lock_guard

간단한 RAII 클래스이다.
락을 즉시 획득하고, 임의로 락 해제는 불가능하다.

항상 락이 유지되어야 하는 간단한 임계 구역에 적합하다.

성능

세 락 객체 중 가장 가볍다. 오버헤드가 거의 없다.

언제 사용?

간단하게 락만 필요할 때 사용한다.
락 해제/재획득 같은 유연성이 필요 없을 때 사용한다.


std::unique_lock

std::lock_guard보다 유연한 락 관리 도구이다.

락을 바로 거는 것이 아닌 지연된 락 획득이 가능하다. (defer_lock)
락을 명시적으로 해제/재획득 가능하다.
타이밍 제한(예: try_lock_for) 지원한다.
조건 변수와 함께 사용 가능.

성능

std::lock_guard보다 무겁지만, 유연성 때문에 필수 상황에 적합하다.

언제 사용?

락 해제/재획득이 필요하거나 조건 변수(std::condition_variable)를 사용할 때.
타임아웃 기능이 필요할 때.


std::mutex mtx;
void critical_section() {
    std::unique_lock<std::mutex> lock(mtx, std::defer_lock); // 바로 락을 걸지 않음
    lock.lock();  // 필요할 때 락을 획득
    // 락이 걸린 상태에서 실행
    lock.unlock(); // 락 해제
    lock.lock();  // 다시 락 획득 가능
}

std::shared_lock

윈도우 API의 SRWLock과 같은 기능이다.

다중 읽기 락을 제공하는 도구이다.

읽기 전용 락으로, 여러 스레드가 동시에 읽을 수 있다.

쓰기 락(std::unique_lock)과 함께 사용할 때, 쓰기 락이 우선권을 가진다.
예를 들어 A 스레드가 읽기 락을 얻어서 작업 중에 있고 B 스레드는 읽기 락을 대기하고 있고 C 스레드는 쓰기 락으로 대기를 하고 있다면, A가 읽기 락을 반환하면 C 스레드가 먼저 락을 선점한다는 의미이다.

락 해제/재획득 가능하다.

성능

읽기 락은 상대적으로 가볍다.
하지만 쓰기 락이 필요한 경우 성능이 낮아질 수 있음.

언제 사용?

데이터를 여러 스레드가 읽기만 하고, 쓰기는 드물게 발생하는 경우.
읽기와 쓰기가 명확히 구분되는 시나리오에서 쓴다.

std::shared_mutex smtx;
void read_data() {
    std::shared_lock<std::shared_mutex> lock(smtx); // 읽기 락
    // 데이터를 읽는 동안 다른 읽기 작업은 허용됨
}

void write_data() {
    std::unique_lock<std::shared_mutex> lock(smtx); // 쓰기 락
    // 쓰기 중에는 읽기/쓰기 모두 차단됨
}
profile
게임 서버 프로그래밍을 공부하고 있습니다.

0개의 댓글