뮤텍스 (Mutex)의 개념
멀티스레드 프로그래밍에서 공유 자원에 대한 동시 접근을 제어하는 것은 매우 중요합니다.
이를 위해 C++은 뮤텍스(mutex)와 락(lock)을 제공합니다.
뮤텍스(Mutual Exclusion의 줄임말)는 여러 스레드가 공유 자원에 동시에 접근하는 것을 방지하는 동기화 객체입니다.
C++에서는 <mutex> 헤더에 정의된 std::mutex
클래스를 사용하여 뮤텍스를 구현합니다.
mtx.lock()
은 뮤텍스를 잠그고, mtx.unlock()
은 뮤텍스를 해제합니다.
락 가드 (Lock Guard)
std::lock_guard
는 RAII(Resource Acquisition Is Initialization) 원칙을 따르는 락 객체로, 생성 시 뮤텍스를 자동으로 잠그고 소멸 시 자동으로 해제합니다.
유니크 락 (Unique Lock)
std::unique_lock
은 std::lock_guard
보다 더 유연한 락 객체입니다.
락의 소유권을 이전하거나 조건 변수와 함께 사용할 수 있습니다.
데드락 (Deadlock)
데드락은 두 개 이상의 스레드가 서로 상대방이 가진 리소스를 기다리며 무한히 대기하는 상황입니다.
std::lock과 std::scoped_lock
C++ 17부터는 std::scoped_lock
을 사용하여 여러 뮤텍스를 한 번에 안전하게 잠글 수 있습니다.
재귀적 뮤텍스 (Recursive Mutex)
std::recursive_mutex
는 같은 스레드에서 여러 번 잠글 수 있는 뮤텍스입니다.
연습 문제
- 생산자-소비자 문제를 구현하세요. 생산자 스레드는 데이터를 생성하여 버퍼에 넣고, 소비자 스레드는 버퍼에서 데이터를 꺼내 처리합니다. 뮤텍스와 조건 변수를 사용하여 동기화를 구현하세요.
- 읽기-쓰기 락을 구현하세요. 여러 스레드가 동시에 읽기 작업을 수행할 수 있지만, 쓰기 작업은 배타적으로 수행되어야 합니다.
- 데드락을 방지하기 위한 계층적 뮤텍스 잠금 전략을 구현하세요. 여러 개의 뮤텍스를 사용할 때 항상 정해진 순서대로 잠그도록 합니다.
참고자료
- C++ Concurrency in Action (2nd Edition) by Anthony Williams
- Effective Modern C++ by Scott Meyers (Item 35-40)
- C++ 표준 문서의 스레드와 동기화 관련 섹션
- CppCon 발표 영상들 - 동시성 프로그래밍 관련 세션들
- "The Art of Multiprocessor Programming" by Maurice Herlihy and Nir Shavit