블로그는 나의 힘!
[ 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
[ Programing ]/Server2022. 12. 5. 20:12

- 리소스 자원을 공유하고 있기 때문에, 자원에 대한 교착상태(자원 접근에 대한 싸움)) 발생 가능성 있음.
- List를 순회하고 있는데, 다른 스레드에서 List를 삭제함. (=>error발생)

- 화장실 이슈
  동기화 잘 되지 않으면 내가 화장실을 사용하는데 남이 문을 막 열고 들어옴.
  동기화 잘 되면 내가 쓰면서 문을 잠그기 때문에 남이 들어올 수 없고, 내가 사용이 끝나면 그 뒤에 들어올 수 있음.



출처 : https://blog.naver.com/minimay9250/222904612848

 

[OS] 멀티 스레드의 동기화

* 동기화(Synchronization)란? 여러 스레드가 한 리소스를 사용하려고 할 때 사용하려는 스레드 하나를 제...

blog.naver.com


 
# 스레드 동기화 방법

1. 실행 순서의 동기화

   스레드의 실행순서를 정의하고, 이 순서에 반드시 따르도록 하는 것

2. 메모리 접근에 대한 동기화
   메모리 접근에 있어서 동시 접근을 막는 것
   실행 순서가 중요한 상황이 아니고, 한 순간에 하나의 스레드만 접근하면 되는 상황을 의미


# 동기화 기법의 종류

1. 유저 모드 동기화
   동기화가 진행되는 과정에서 커널 코드가 실행되지 않는 동기화 기법
   동기화를 위해서 커널 모드로의 전환이 불필요하기 때문에 성능에 이점이 있으나 그만큼 기능상 제한도 존재.

(1) 크리티컬 섹션(Critical Section)
   - 임계 영역을 화장실에 비유하면, 화장실에 들어가기 위해서는 화장실 앞에 걸려있는 열쇠를 가져가야만 한다. 
     열쇠가 걸려있다면 이 열쇠로 문을 열고 화장실에 들어가면 된다. 
     화장실 사용이 끝났다면 다시 열쇠를 화장실 앞에 걸어 놓는다.

   - 핵심은 열쇠를 얻은 사람만이 화장실에 들어갈 수 있다는 것이다.

   - 해당 프로세스 내에서만 사용할 수 있다.

   - lock(object) {Todo} => lock하면 {}안의 Todo가 끝날때까지 다른 스레드들이 접근 못한다.

(2) 인터락 함수
   - 인터락 함수는 함수 내부적으로 한 순간에 하나의 스레드에 의해서만 실행되도록 동기화 되어있다.


2. 커널모드 동기화
   커널에서 제공하는 동기화 기능을 활용하는 방법. 
   동기화에 관련된 함수가 호출될 때마다 커널 모드로의 변경이 필요하고 이는 성능 저하로 이어진다. 
   하지만 그만큼 유저 모드 동기화에서 제공하지 못하는 기능을 제공받을 수 있다.

(1) 뮤텍스
   - 임계구역을 가진 스레드들의 실행시간이 서로 겹치지 않고 각각 단독으로 실행되도록 하는 기술

   - 한 프로세스에 의해 소유될 수 있는 Key를 기반으로 한 상호배체 기법

   - Key 해당하는 어떤 객체가 있으며 이 객체를 소유한 스레드/프로세스만이 공유자원에 접근할 수 있음

(2) 세마포어
   - 사용하고 있는 스레도/프로세스 수를 공통으로 관리하는 하나의 값을 이용해 상호배제를 달성함.

   - 공유자원에 접근할 수 있는 프로세스의 최대 허용치만큼 동시에 사용자가 접근할 수 있으며, 
     각 프로세스는 세마포어의 값을 확인하고 변경할 수 있음.

   - 자원을 사용하지 않는 상태가 될 때, 대기하던 프로세스가 즉시 자원을 사용하고, 
     이미 다른 프로세스에 의해 사용중이라는 사실을 알게되면, 재시도 전에 일정시간 대기해야함.



Posted by Mister_Q
[ Programing ]/Other2022. 11. 23. 12:17

1. 환경 설정.
설정 - 환경설정에서 다크모드




2. 스타일 설정.

설정 - 스타일 설정에서


테마 선택 : Black board
언어 : Global Styles (추천)
형식 : Global override (추천)





'[ Programing ] > Other' 카테고리의 다른 글

링크 모음  (0) 2024.07.03
색깔 값 찾기  (0) 2024.07.03
Notepad++ 에서 JSON viewer 사용하기.  (0) 2022.11.23
JSON 유효성 검사기  (0) 2022.02.07
코드 비교 체크. diffchecker  (0) 2022.01.25
Posted by Mister_Q