NeuroWhAI의 잡블로그

[C++] shared_mutex, shared_lock 사용 예시 본문

개발 및 공부/언어

[C++] shared_mutex, shared_lock 사용 예시

NeuroWhAI 2018. 10. 19. 21:14


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

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


딱히 쓸 일이 없어서 몰랐는데 책에서 나왔으니 한번 봤습니다.

shared_mutex 헤더에 있다고 하네요.


아래는 사용 예시. (mutex와는 별개의 이유로 C++17 이상에서만 컴파일 됩니다!)

#include <iostream>
#include <type_traits>
#include <thread>
#include <mutex>
#include <shared_mutex>

// 원자적인 카운터
class AtomicCounter
{
private:
    int m_counter = 0;
    mutable std::shared_mutex m_mutex;
    
public:
    int getCount() const
    {
        std::shared_lock lk{ m_mutex };
        return m_counter;
    }
    
    void increase()
    {
        std::lock_guard lk{ m_mutex };
        ++m_counter;
    }
};

AtomicCounter counter;

// 표준 출력 동기화용 뮤텍스. (집중할 부분 아님)
std::mutex coutMutex;

// counter의 값을 증가시키는 작업 함수.
void incJob()
{
    counter.increase();
}

// counter의 값을 출력하는 작업 함수.
void printJob()
{
    std::lock_guard lk{ coutMutex };
    std::cout << counter.getCount() << std::endl;
}

// 쪼인 올!
template <typename... TArgs>
void joinAll(TArgs&&... args)
{
    static_assert((std::is_base_of_v<std::thread, std::decay_t<TArgs>> && ...),
        "스레드만 받아요...");
    (args.join(), ...);
}

int main()
{
    std::thread t1{ printJob };
    std::thread t2{ incJob };
    std::thread t3{ printJob };
    std::thread t4{ incJob };
    std::thread t5{ printJob };
    std::thread t6{ incJob };
    
    joinAll(t1, t2, t3, t4, t5, t6);
    
    return 0;
}

보시면 읽기(getCount) 작업엔 공유된(?) 락을 걸고 있는데 읽기만 하는 것은 여러 스레드가 수행해도 괜찮기 때문이며 한 스레드라도 읽고 있을 때는 쓰기 작업이 막힙니다.

쓰기(increase) 작업엔 일반적인 락을 걸고 있는데 오직 하나의 쓰레드만 동시에 쓸 수 있고 쓰는 동안은 읽기 작업이 막힙니다.

참고로 읽기, 쓰기가 잘 동기화 되긴 하지만 출력은 미정의 동작입니다.


참 쉽죠?



Comments