• 티스토리 홈
starryeye
  • 프로필사진
    starryeye
    • 분류 전체보기 (189)
      • C++ (17)
      • Java (24)
      • OOP (5)
      • Spring Reactive Stack (12)
        • Reactive Streams (3)
        • Netty (4)
        • Reactor (1)
        • Webflux (3)
        • DB, Cache 연동 (1)
      • Spring (90)
        • Core (17)
        • MVC (33)
        • Client (2)
        • Security (4)
        • DB, Cache 연동 (33)
      • DataBase (12)
        • RDBMS (2)
        • NoSQL (10)
      • Message Broker (6)
      • Web (4)
      • Network (4)
      • 대규모 시스템 설계 (15)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • [C++] window, linux lock
        2022년 07월 15일
        • starryeye
        • 작성자
        • 2022.07.15.:33
        반응형

         

         

        lock 이란.. 공유되는 자원에 동시 접근하여 데이터의 신뢰도를 떨어트리는 현상을 방지하고자 함에 있다.

        따라서 lock이라는 개념을 도입하여 한번에 하나의 작업을 진행하게 한다.

         

        그렇다면.. 여러 스레드에서 어떻게.. 그 자원에 lock이 걸려있는지 알 수 있을까?

        -> 아래 os별 lock을 구현 하는 코드로 알아보자

         

        window

        window.h 헤더파일을 사용한다.

        ///////////////
        헤더 파일
        class lockTest {
        	
            함수 선언 생략..
        
            CRITICAL_SECTION* p_lock;
        }
        ///////////////
        cpp 파일
        lockTest::lockTest() {
            p_lock = NULL;
        
            initialize();
        }
        lockTest::~lockTest() {
        
            destroy();
        }
        int lockTest::initialize() {
        
            CRITICAL_SECTION* cs = new(std::nothrow) CRITICAL_SECTION;
            if(!cs)
            	return -1;
            p_lock = cs;
            InitializeCriticalSection(cs);
        }
        void lockTest::destroy() {
            if(!p_lock)
                return;
            
            cs = p_lock;
            DeleteCriticalSection(cs);
            delete cs;
            cs = NULL;
            p_lock = NULL;
        }
        void lockTest::lockStart() {
        
            if(p_lock)
                return;
            EnterCriticalSection(p_lock);
        }
        void lockTest::lockEnd() {
        
            if(p_lock)
            	return;
            
            LeaveCriticalSection(p_lock);
            
        }
        bool lockTest::lockTry() {
        
            if(!p_lock)
            	return false;
            
            if(!TryEnterCriticalSection(p_lock)
            	return false;
            
            return true;
        }

        <참고>

        위 lockTest라는 클래스는..

        자원이 존재하는 다른 클래스에서 맴버변수로 lockTest 를 선언 해놓고 사용할 수 있다.

         

        코드에서 유추 할 수 있듯이..

        하나의 lock 포인터를 공유하는 자원끼리 lock에 대한 공유가 가능하다..

        -> 공유하는 자원이란.. 동일한 락을 사용하는 자원이라는 말이다.

        -> 예제 코드를 보며 더 이해 해보자..

        ///////////////
        헤더파일
        
        class Z {
        	
            func1();
            func2();
            
            lockTest lockA;
        }
        
        ///////////////
        cpp 파일
        
        Z::func1() {
        	lockA.lockStart();
        }
        Z::func2() {
        	lockA.lockStart();
        }

        서로 다른 스레드에서 Z클래스의 동일한 인스턴스에서 func1, func2 함수를 호출 시,

        서로 락의 영향이 생긴다.

         

        참고1>

        -> Z클래스에 lockB라는 lockTest 변수가 생겼고.. func2함수에서 lockB에 대한 lockStart 함수를 호출한다고 가정해보자..

        -> 서로다른 스레드에서 func1, func2 함수를 호출 하는 것은 아무런 영향이 없다.

        -> 왜냐하면.. lockTest의 실질적인 p_lock 변수가 .. 서로 다른 포인터이기 때문이다.

         

        참고2>

        -> Class Z말고 Class X에 lockTest 변수가 있는데.. X와 Z의 lockTest 변수가 포인터로 선언되어있으며

        (lockTest 얕은 복사 관점 추가 구현 필요..)

        -> 동일하다면... 다른 클래스라 할지라도 lock 포인터를 공유하기 때문에 서로 영향이 생긴다.

         

        결국..

        같은 lock 이냐가 중요하며.. lockStart가 현재 걸려있냐 아니냐에 따라 의미가 생긴다.

         

         

        linux와 cross compile

        window 버전을 조금 더 리뉴얼 해보자..

        pthread.h 헤더파일을 사용한다.

        ///////////////
        헤더 파일
        class lockTest {
        	
            함수 선언 생략..
            
            void* p_lock;
        }
        
        ///////////////
        cpp 파일
        lockTest::lockTest() {
        
            p_lock = NULL;
            initialize();
        }
        
        lockTest::~lockTest() {
        
            destroy();
        }
        
        int lockTest::initialize() {
        
        #ifdef _MSC_VER
            CRITICAL_SECTION* cs = new(std::nothrow) CRITICAL_SECTION;
            if(!cs)
            	return -1;
            p_lock = (void*)cs;
            InitializeCriticalSection(cs);
        #else
            pthread_mutex_t* pm = new(std::nothrow) pthread_mutex_t;
            p_lock = (void*)pm;
            
            pthread_mutexattr_t pma;
            pthread_mutexattr_init(&pma);
            
            pthread_mutex_init(pm, &pma);
        #endif
        
            return 0;
        }
        
        void lockTest::destroy() {
        
            if(!p_lock)
            	return;
                
        #ifdef _MSC_VER
            CRITICAL_SECTION* cs = (CRITICAL_SECTION*)p_lock;
            
            DeleteCriticalSection(cs);
            delete cs;
            cs = NULL;
        #else
            pthread_mutex_t* pm = (pthread_mutex_t*)p_lock;
            
            pthread_mutex_destroy(pm);
            delete pm;
            pm = NULL;
        #endif
        
            p_lock = NULL;
            
        }
        
        void lockTest::lockStart() {
        
            if(p_lock)
            	return;
                
        #ifdef _MSC_VER
            EnterCriticalSection((CRITICAL_SECTION*)p_lock);
        #else
        	pthread_mutex_lock((pthread_mutex_t*)p_lock);
        #endif
        }
        
        void lockTest::lockEnd() {
        
            if(p_lock)
            	return;
                
        #ifdef _MSC_VER    
            LeaveCriticalSection((CRITICAL_SECTION*)p_lock);
        #else
        	pthread_mutex_unlock((pthread_mutex_t*)p_lock);
        #endif  
        }
        
        bool lockTest::lockTry() {
            
            if(!p_lock)
            	return false;
                
        #ifdef _MSC_VER    
            if(!TryEnterCriticalSection(p_lock)
            	return false;
        #else
        	if(pthread_mutex_trylock((pthread_mutex_t*)p_lock) != 0)
            	return false;
        #endif
        
            return true;
        }

        cross compile을 위하여..

        p_lock 의 자료형 변경과 전처리기를 이용하였다.

        뮤텍스 락을 사용한다.

         

        반응형

        'C++' 카테고리의 다른 글

        [Effective Modern C++] 항목 8  (0) 2022.08.14
        [Effective Modern C++] 항목 5  (0) 2022.08.14
        [C++] move와 copy  (0) 2022.07.15
        [C++] Template Type check  (0) 2022.07.15
        정적 vs 동적 링크 라이브러리  (0) 2022.04.03
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바