Skip to content

2014 10 24 mutex 클래스, lock 클래스

Jamie edited this page Jul 5, 2015 · 1 revision

mutex 클래스

상호 배제(mutual exclusion)를 위해 C++11부터 지원하는 클래스입니다. mutex 클래스의 종류는 아래와 같습니다.

  • 일반 mutex 클래스
    • std::mutex
    • std::recursive_mutex
  • 타임아웃 mutex 클래스
    • std::timed_mutex
    • std::recursive_timed_mutex

일반 mutex 클래스의 try_lock() 메서드에서 락 획득을 시도하고 즉시 리턴하는 것과는 달리, 타임아웃 mutex 클래스는 아래 두가지 메소드를 추가로 지원합니다.

  • try_lock_for() 주어진 시간 간격만큼 락 획득을 시도합니다.
  • try_lock_util() 주어진 절대 시간까지 락 획득을 시도합니다.

일반 mutex 클래스는 락을 점유한 스레드에서 다시 락 획득을 시도하면 실패하는 반면, 재귀(recursive) mutex 클래스는 획득이 가능합니다. 단, 락의 획득과 해제 횟수는 반드시 동일해야 합니다.

lock 클래스

mutex 클래스가 그냥 포인터라면 lock 클래스는 스마트 포인터에 비유할 수 있습니다. new로 생성된 객체가 한번만, 그리고 반드시 delete 되도록 스마트 포인터를 통해 편리하게 관리하듯이, lock 클래스를 통해 mutex 객체의 락을 획득하고 소멸자에서 자동으로 락을 해제하게 됩니다. 아래 두가지 종류의 락 클래스가 있습니다.

  • std::lock_guard 생성자에서 락 획득을 시도하고 점유할 때까지 블록됩니다.
  • std::unique_lock 생성자에서 락 획득을 하거나 이미 점유한 mutex 객체를 사용하거나, try_lock()을 사용하는 등 락 획득 정책에 따른 다양한 생성자를 제공합니다.

그리고 여러 개의 mutex 객체를 한꺼번에 점유할 수 있도록 가변 인자 템플릿 함수인 제네릭 lock() 함수를 제공합니다. 제네릭 lock() 함수는 인자로 주어진 mutex 객체들을 인자 순서대로 획득을 시도하고, 시도 중 실패할 경우 모든 락을 자동으로 해제합니다.

아래는 이러한 예제입니다.

std::mutex mut1;
std::mutex mut2;

void do_something() {
  std::unique_lock<std::mutex> lock1(mut1, std::defer_lock_t());
  std::unique_lock<std::mutex> lock2(mut2, std::defer_lock_t());

  lock(lock1, lock2);
  // 이후 코드에서는 모든 락을 점유하고 함수 리턴 시 해제됩니다.
}

위에서 defer_lock_t 객체를 넘겨주는 것은 락 생성과 동시에 획득을 시도하지 않고 추후에 명시적으로 시도하도록 하기 위함입니다.

Clone this wiki locally