블로그는 나의 힘!
[ Programing ]/Server2022. 12. 5. 21:13

shared_mutex?

읽기/쓰기 락을 지원하는 뮤텍스.
데이터를 수정하지 않고 읽기만 한다면, n개의 스레드에서 접근하더라도 아무런 문제가 없다.

하지만 쓰기, 수정이 일어나야 한다면? 
읽기도 막아야한다.

따라서, 읽기만 하는 상황에선 읽기 락을 걸어 n개의 스레드에서 접근이 가능하도록 하고,
쓰기를 해야 할 상황에선 1개의 스레드에서만 접근 가능하도록 하는 락을 지원하는 뮤텍스이다. 
이 락 readers writer lock이라고도 불림.




지금(2015/12/xx) 기준으론 boost 라이브러리에만 존재하지만, 
c++17에는 공식적으로 편입될 예정(http://en.cppreference.com/w/cpp/thread/shared_mutex)

헤더는 #include <boost/shared_mutex.hpp>
그리고 boost::shared_mutex를 선언한다.

 

# 읽기 락(n개의 스레드가 접근할 수 있는 락)
shared_lock을 쓴다.
boost::shared_lock<boost::shared_mutex> rlock{ mutex_ };



# 쓰기 락(1개의 스레드만 접근할 수 있는 락)
unique_lock을 쓴다.
boost::unique_lock<boost::shared_mutex> wlock{ mutex_ };




# 읽기 락과 쓰기 락을 전환하고 싶을 때.
기본적으로 upgrade_lock을 선언. upgrade_lock만 선언된 상황에선 읽기로 락을 건다.
그리고 쓰기 락으로 전환되어야 할 부분에서 boost::upgrade_to_unique_lock을 사용해 
읽기 락 => 쓰기 락으로 변경.

//!< 이 선언만으론 읽기 락이 됨. 
boost::upgrade_lock<boost::shared_mutex> rlock{ mutex_ }; 

//!< ... do something

//!< 쓰기락으로 업그레이드.
boost::upgrade_lock<boost::shared_mutex> wlock{ rlock }; 



//!< 쓰기 락으로 전환할 상황이 생겼다면..!

//!< 읽기 락을 쓰기 락으로 바꿈.
boost::upgrade_to_unique_lock<boost::shared_mutex> wlock{ rlock }; 


* 코드에 적용된 예를 보자.

    //!< 읽기 락을 얻음.
    boost::upgrade_lock<boost::shared_mutex> lock{ mutex_ };
 
    //!< 검색자를 획득.
    auto& finder = user_cache.get<user_container::idx_type::id>();
 
    auto it = finder.find(id.data());

    //!< 캐시에 정보가 없을 때.
    if (it == finder.end())
    { 
         //!< db로부터 데이터를 획득을 시도.
         auto data = load_user_account_from_db(id);

    //!< 데이터를 획득했을 때
    if (data)
    {
         auto userdata = *data;
         account acc;
         acc.id = userdata.id.data();
         acc.nickname = userdata.nickname.data();
         acc.usercode = userdata.usercode;
         acc.pw = userdata.pw.data();
         acc.num_lose = userdata.num_lose;
         acc.num_win = userdata.num_win;
 
         //!< 읽기 락을 쓰기 락으로 전환.
         boost::upgrade_to_unique_lock<boost::shared_mutex> wlock{ lock };
 
         //!< 캐시에 삽입합니다.
         user_cache.insert(acc);
         handler(data);
    }




여튼 핵심은
upgrade_lock 
=> 읽기/쓰기 락을 전환할 수 있는 락인데 기본적으론 읽기 락이다. 

upgrade_to_unique_lock 
=> 업그레이드 락(읽기 락)을 쓰기 락으로 바꿈


 

참고 : 
   http://stackoverflow.com/questions/7378266/upgrading-boostshared-lock-to-exclusive-lock
   http://boost.2283326.n4.nabble.com/boost-shared-locks-and-boost-upgrade-locks-td4171304.html
   http://blog.naver.com/wnsdud98/130132612632



출처 : https://zepeh.tistory.com/297

 

shared_mutex, 그리고 upgrade_lock.

shared_mutex? 읽기/쓰기 락을 지원하는 뮤텍스.데이터를 수정하지 않고 읽기만 한다면, n개의 스레드에서 접근하더라도 아무런 문제가 없다.하지만 쓰기, 수정이 일어나야 한다면? 읽기도 막아야한

zepeh.tistory.com



 

Posted by Mister_Q