33 Thread support library [thread]

33.4 Mutual exclusion [thread.mutex]

33.4.3 Mutex requirements [thread.mutex.requirements]

33.4.3.4 Shared mutex types [thread.sharedmutex.requirements]

The standard library types shared_­mutex and shared_­timed_­mutex are shared mutex types.
Shared mutex types shall meet the requirements of mutex types, and additionally shall meet the requirements set out below.
In this description, m denotes an object of a shared mutex type.
In addition to the exclusive lock ownership mode specified in [thread.mutex.requirements.mutex], shared mutex types provide a shared lock ownership mode.
Multiple execution agents can simultaneously hold a shared lock ownership of a shared mutex type.
But no execution agent shall hold a shared lock while another execution agent holds an exclusive lock on the same shared mutex type, and vice-versa.
The maximum number of execution agents which can share a shared lock on a single shared mutex type is unspecified, but shall be at least 10000.
If more than the maximum number of execution agents attempt to obtain a shared lock, the excess execution agents shall block until the number of shared locks are reduced below the maximum amount by other execution agents releasing their shared lock.
The expression m.lock_­shared() shall be well-formed and have the following semantics:
Requires: The calling thread has no ownership of the mutex.
Effects: Blocks the calling thread until shared ownership of the mutex can be obtained for the calling thread.
If an exception is thrown then a shared lock shall not have been acquired for the current thread.
Postconditions: The calling thread has a shared lock on the mutex.
Return type: void.
Synchronization: Prior unlock() operations on the same object shall synchronize with this operation.
Throws: system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • operation_­not_­permitted — if the thread does not have the privilege to perform the operation.
  • resource_­deadlock_­would_­occur — if the implementation detects that a deadlock would occur.
The expression m.unlock_­shared() shall be well-formed and have the following semantics:
Requires: The calling thread shall hold a shared lock on the mutex.
Effects: Releases a shared lock on the mutex held by the calling thread.
Return type: void.
Synchronization: This operation synchronizes with subsequent lock() operations that obtain ownership on the same object.
Throws: Nothing.
The expression m.try_­lock_­shared() shall be well-formed and have the following semantics:
Requires: The calling thread has no ownership of the mutex.
Effects: Attempts to obtain shared ownership of the mutex for the calling thread without blocking.
If shared ownership is not obtained, there is no effect and try_­lock_­shared() immediately returns.
An implementation may fail to obtain the lock even if it is not held by any other thread.
Return type: bool.
Returns: true if the shared ownership lock was acquired, false otherwise.
Synchronization: If try_­lock_­shared() returns true, prior unlock() operations on the same object synchronize with this operation.
Throws: Nothing.

33.4.3.4.1 Class shared_mutex [thread.sharedmutex.class]

namespace std {
  class shared_mutex {
  public:
    shared_mutex();
    ~shared_mutex();

    shared_mutex(const shared_mutex&) = delete;
    shared_mutex& operator=(const shared_mutex&) = delete;

    // Exclusive ownership
    void lock(); // blocking
    bool try_lock();
    void unlock();

    // Shared ownership
    void lock_shared(); // blocking
    bool try_lock_shared();
    void unlock_shared();

    using native_handle_type = implementation-defined; // See [thread.req.native]
    native_handle_type native_handle();                // See [thread.req.native]
  };
}
The class shared_­mutex provides a non-recursive mutex with shared ownership semantics.
The class shared_­mutex shall satisfy all of the shared mutex requirements.
It shall be a standard-layout class (Clause [class]).
The behavior of a program is undefined if:
  • it destroys a shared_­mutex object owned by any thread,
  • a thread attempts to recursively gain any ownership of a shared_­mutex, or
  • a thread terminates while possessing any ownership of a shared_­mutex.
shared_­mutex may be a synonym for shared_­timed_­mutex.