Namespaces
Variants

std:: shared_mutex

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
(C++11)
shared_mutex
(C++17)
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
헤더 파일에 정의됨 <shared_mutex>
class shared_mutex ;
(C++17부터)

shared_mutex 클래스는 공유 데이터가 여러 스레드에 의해 동시에 접근되는 것을 보호하기 위해 사용할 수 있는 동기화 기본 요소입니다. 배타적 접근을 용이하게 하는 다른 뮤텍스 유형과 달리, shared_mutex는 두 가지 수준의 접근을 가집니다:

  • shared - 여러 스레드가 동일한 뮤텍스의 소유권을 공유할 수 있습니다.
  • exclusive - 뮤텍스를 소유할 수 있는 스레드는 오직 하나뿐입니다.

한 스레드가 exclusive lock을 획득한 경우( lock , try_lock 통해), 다른 스레드들은 lock을 획득할 수 없습니다( shared lock 포함).

한 스레드가 shared lock을 획득한 경우( lock_shared , try_lock_shared 를 통해), 다른 스레드는 exclusive lock을 획득할 수 없지만, shared lock은 획득할 수 있습니다.

오직 exclusive 잠금이 어떤 스레드에서도 획득되지 않은 경우에만, shared 잠금을 여러 스레드가 획득할 수 있습니다.

하나의 스레드 내에서는 동시에 하나의 락( shared 또는 exclusive )만 획득할 수 있습니다.

공유 뮤텍스는 공유 데이터가 여러 스레드에 의해 동시에 안전하게 읽힐 수 있지만, 다른 스레드가 동시에 읽거나 쓰고 있지 않을 때만 스레드가 동일한 데이터를 쓸 수 있는 경우에 특히 유용합니다.

shared_mutex 클래스는 SharedMutex StandardLayoutType 의 모든 요구사항을 충족합니다.

목차

멤버 타입

멤버 타입 정의
native_handle_type ( 선택적* ) 구현 정의

멤버 함수

뮤텍스를 생성함
(public member function)
뮤텍스를 파괴함
(public member function)
operator=
[deleted]
복사 할당 불가
(public member function)
배타적 잠금
뮤텍스를 잠금, 사용 불가능할 경우 차단됨
(public member function)
뮤텍스 잠금을 시도함, 사용 불가능할 경우 반환됨
(public member function)
뮤텍스 잠금을 해제함
(public member function)
공유 잠금
공유 소유권을 위해 뮤텍스를 잠금, 사용 불가능할 경우 차단됨
(public member function)
공유 소유권을 위해 뮤텍스 잠금을 시도함, 사용 불가능할 경우 반환됨
(public member function)
뮤텍스 잠금을 해제함 (공유 소유권)
(public member function)
네이티브 핸들
기본 구현 정의 네이티브 핸들 객체를 반환함
(public member function)

예제

아래 출력은 단일 코어 머신에서 생성되었습니다. thread1 이 시작되면 첫 번째 루프 진입 시 increment() 를 호출한 후 get() 를 호출합니다. 그러나 반환된 값을 std:: cout 에 출력하기 전에 스케줄러가 thread1 을 슬립 상태로 전환하고 thread2 를 깨웁니다. 이로 인해 thread2 는 세 번의 루프 반복을 모두 한 번에 실행할 충분한 시간을 갖게 됩니다. thread1 으로 돌아와서, 여전히 첫 번째 루프 반복 중인 상태에서 마침내 카운터 값의 로컬 복사본인 1 std::cout 에 출력한 후 나머지 두 번의 루프 반복을 실행합니다. 멀티코어 머신에서는 스레드가 슬립 상태로 전환되지 않으며, 출력이 오름차순으로 나타날 가능성이 더 높습니다.

#include <iostream>
#include <mutex>
#include <shared_mutex>
#include <syncstream>
#include <thread>
class ThreadSafeCounter
{
public:
    ThreadSafeCounter() = default;
    // Multiple threads/readers can read the counter's value at the same time.
    unsigned int get() const
    {
        std::shared_lock lock(mutex_);
        return value_;
    }
    // Only one thread/writer can increment/write the counter's value.
    void increment()
    {
        std::unique_lock lock(mutex_);
        ++value_;
    }
    // Only one thread/writer can reset/write the counter's value.
    void reset()
    {
        std::unique_lock lock(mutex_);
        value_ = 0;
    }
private:
    mutable std::shared_mutex mutex_;
    unsigned int value_{};
};
int main()
{
    ThreadSafeCounter counter;
    auto increment_and_print = [&counter]()
    {
        for (int i{}; i != 3; ++i)
        {
            counter.increment();
            std::osyncstream(std::cout)
                << std::this_thread::get_id() << ' ' << counter.get() << '\n';
        }
    };
    std::thread thread1(increment_and_print);
    std::thread thread2(increment_and_print);
    thread1.join();
    thread2.join();
}

가능한 출력:

123084176803584 2
123084176803584 3
123084176803584 4
123084185655040 1
123084185655040 5
123084185655040 6

참고 항목

공유 상호 배제 기능을 제공하고 타임아웃으로 잠금을 구현함
(class)
이동 가능한 공유 뮤텍스 소유권 래퍼를 구현함
(class template)
이동 가능한 뮤텍스 소유권 래퍼를 구현함
(class template)