반응형

cpp mutex

include <mutex>


+ mutex 사용하기

std::mutex mtx ;


void func(int id, int &v) {

   for (int i=0; i<10; i++) {

     mtx.lock() ;

    ++v ;

    mtx.unlock() ;

   }

}

int v=0 ;

std::thread t1 (func, 0, std::ref(v) ) ;

std:;thread t2(func, 1, std::ref(v) ) ;

t1.join();

t2.join() ;


-lock() ; 다른 쓰레드에 의해 lock되어 있지 않는 경우, 현재 쓰레드에서 락을 건다. unlock을 할 때까지 현재 쓰레드가 뮤텍스를 소유함. 

이미 다른쓰레드가 뮤텍스를 소유하고 있으면, 해제될때까지 블로킹 된다.

- lock을 얻은 상태에서 또 lock()을 하면 안된다. 데드락 발생.  (중복 lock을 하려면 recursive_mutex 사용)


+ bool try_lock() ; lock을 얻지 못하면 바로 리턴한다. 블로킹되지 않는 것이 lock()과 차이. 

뮤텍스를 얻었으면 true를 리턴하고, 작업 완료시 unlock()을 해주어야 한다.

다른 쓰레드가 뮤텍스 소유하고 있으면 false를 바로 리턴한다.


+ recursive_mutex  ; mutex와 비슷하나, lock 등급이 가능.

락을 얻은 상태에서 또 락을 얻을 수 있다. 뮤텍스 소유 레벨을 올림.

나중에 unlock()을 lock() 횟수만큼 해줘야 한다.



==> Mutex를 직접사용하지 말고 아래(lock_guard, unique_lock) 를 사용하기를 권장함.


+ lock_guard  ; 함수 내부에서 사용하여 간단하게 동기화 처리.

내부적으로 mutex를 사용하여 항상 락이 되도록 유지.

constructor에서 락을 얻고, destructor에서 언락을 한다.

std::mutex mtx ;

void func(int id) {

try {

   std::lock_guard<std::mutex> lck(mtx) ;

} catch ( std::logic_error & ) {

}

}


+unique_lock ; 뮤텍스를 사용하여 동기화 처리. lock_guard와 비슷하나 구동 시점을 지정할 수 있다.

lock, unlock을 사용 가능하며, 굳이 사용 안 해도 lock_guard 처럼 작동한다.

함수 일부분내에서 동기화 해제해도 되는 구간이 있을 경우에 사용하면 될 것 같다.

생성시점에 락을 안 걸 수도 있다.

guard(mutex, std::defer_lock) ; 이렇게 초기화하면 락을 얻지 않는다.






'Develop > C&CPP' 카테고리의 다른 글

stack / queue  (0) 2018.06.12
cstring  (0) 2018.06.11
thread  (0) 2018.06.09
utility  (0) 2018.06.08
fstream 1 basic_ifstream  (0) 2018.06.07

+ Recent posts