[thread.sharedmutex.requirements]

# 32 Concurrency support library [[thread]](./#thread)

## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.sharedmutex.requirements)

### 32.6.4 Mutex requirements [[thread.mutex.requirements]](thread.mutex.requirements#thread.sharedmutex.requirements)

#### 32.6.4.4 Shared mutex types [thread.sharedmutex.requirements]

#### [32.6.4.4.1](#general) General [[thread.sharedmutex.requirements.general]](thread.sharedmutex.requirements.general)

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7815)

The standard library types shared_mutex and shared_timed_mutex are [*shared mutex types*](#def:shared_mutex_types "32.6.4.4.1 General [thread.sharedmutex.requirements.general]")[.](#general-1.sentence-1)

Shared mutex types meet the requirements of
mutex types ([[thread.mutex.requirements.mutex]](thread.mutex.requirements.mutex "32.6.4.2 Mutex types")) and additionally
meet the requirements set out below[.](#general-1.sentence-2)

In this description,m denotes an object of a shared mutex type[.](#general-1.sentence-3)

[*Note [1](#general-note-1)*:

The shared mutex types meet the [*Cpp17SharedLockable*](thread.req.lockable.shared#:Cpp17SharedLockable "32.2.5.5 Cpp17SharedLockable requirements [thread.req.lockable.shared]") requirements ([[thread.req.lockable.shared]](thread.req.lockable.shared "32.2.5.5 Cpp17SharedLockable requirements"))[.](#general-1.sentence-4)

â *end note*]

[2](#general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7826)

In addition to the exclusive lock ownership mode specified
in [[thread.mutex.requirements.mutex]](thread.mutex.requirements.mutex "32.6.4.2 Mutex types"), shared mutex types provide a[*shared lock*](#def:shared_lock "32.6.4.4.1 General [thread.sharedmutex.requirements.general]") ownership mode[.](#general-2.sentence-1)

Multiple execution agents can
simultaneously hold a shared lock ownership of a shared mutex type[.](#general-2.sentence-2)

But no
execution agent holds a shared lock while another execution agent holds an
exclusive lock on the same shared mutex type, and vice-versa[.](#general-2.sentence-3)

The maximum
number of execution agents which can share a shared lock on a single shared
mutex type is unspecified, but is at least 10000[.](#general-2.sentence-4)

If more than the
maximum number of execution agents attempt to obtain a shared lock, the
excess execution agents block until the number of shared locks are
reduced below the maximum amount by other execution agents releasing their
shared lock[.](#general-2.sentence-5)

[3](#general-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7841)

The expression m.lock_shared() is well-formed and has the
following semantics:

[4](#general-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7845)

*Preconditions*: The calling thread has no ownership of the mutex[.](#general-4.sentence-1)

[5](#general-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7849)

*Effects*: Blocks the calling thread until shared ownership of the mutex can be obtained for the calling thread[.](#general-5.sentence-1)

If an exception is thrown then a shared lock has not been acquired for the current thread[.](#general-5.sentence-2)

[6](#general-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7855)

*Synchronization*: Prior unlock() operations on the same object synchronize with ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races")) this operation[.](#general-6.sentence-1)

[7](#general-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7859)

*Postconditions*: The calling thread has a shared lock on the mutex[.](#general-7.sentence-1)

[8](#general-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7863)

*Return type*: void[.](#general-8.sentence-1)

[9](#general-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7866)

*Throws*: system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#general-9.sentence-1)

[10](#general-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7870)

*Error conditions*: 

- [(10.1)](#general-10.1)

  operation_not_permitted â if the thread does not have the privilege to perform the operation[.](#general-10.1.sentence-1)

- [(10.2)](#general-10.2)

  resource_deadlock_would_occur â if the implementation detects that a deadlock would occur[.](#general-10.2.sentence-1)

[11](#general-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7878)

The expression m.unlock_shared() is well-formed and has the following semantics:

[12](#general-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7881)

*Preconditions*: The calling thread holds a shared lock on the mutex[.](#general-12.sentence-1)

[13](#general-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7885)

*Effects*: Releases a shared lock on the mutex held by the calling thread[.](#general-13.sentence-1)

[14](#general-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7889)

*Return type*: void[.](#general-14.sentence-1)

[15](#general-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7892)

*Synchronization*: This operation [synchronizes with](intro.multithread#def:synchronize_with "6.10.2 Multi-threaded executions and data races [intro.multithread]") subsequentlock() operations that obtain ownership on the same object[.](#general-15.sentence-1)

[16](#general-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7897)

*Throws*: Nothing[.](#general-16.sentence-1)

[17](#general-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7902)

The expression m.try_lock_shared() is well-formed and has the following semantics:

[18](#general-18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7905)

*Preconditions*: The calling thread has no ownership of the mutex[.](#general-18.sentence-1)

[19](#general-19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7909)

*Effects*: Attempts to obtain shared ownership of the mutex for the calling
thread without blocking[.](#general-19.sentence-1)

If shared ownership is not obtained, there is no
effect and try_lock_shared() immediately returns[.](#general-19.sentence-2)

An implementation
may fail to obtain the lock even if it is not held by any other thread[.](#general-19.sentence-3)

[20](#general-20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7916)

*Synchronization*: If try_lock_shared() returns true, prior unlock() operations on the same object synchronize with ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races")) this
operation[.](#general-20.sentence-1)

[21](#general-21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7922)

*Return type*: bool[.](#general-21.sentence-1)

[22](#general-22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7925)

*Returns*: true if the shared lock was acquired, otherwise false[.](#general-22.sentence-1)

[23](#general-23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7929)

*Throws*: Nothing[.](#general-23.sentence-1)

#### [32.6.4.4.2](#thread.sharedmutex.class) Class shared_mutex [[thread.sharedmutex.class]](thread.sharedmutex.class)

[ð](#lib:shared_mutex)

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

 shared_mutex(const shared_mutex&) = delete;
 shared_mutex& operator=(const shared_mutex&) = delete; // exclusive ownershipvoid lock(); // blockingbool try_lock(); void unlock(); // shared ownershipvoid lock_shared(); // blockingbool try_lock_shared(); void unlock_shared(); using native_handle_type = *implementation-defined*; // see [[thread.req.native]](thread.req.native "32.2.3 Native handles") native_handle_type native_handle(); // see [[thread.req.native]](thread.req.native "32.2.3 Native handles")};}

[1](#thread.sharedmutex.class-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7963)

The class shared_mutex provides a non-recursive mutex
with shared ownership semantics[.](#thread.sharedmutex.class-1.sentence-1)

[2](#thread.sharedmutex.class-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7967)

The class shared_mutex meets
all of the shared mutex requirements ([thread.sharedmutex.requirements])[.](#thread.sharedmutex.class-2.sentence-1)

It is a standard-layout class ([[class.prop]](class.prop "11.2 Properties of classes"))[.](#thread.sharedmutex.class-2.sentence-2)

[3](#thread.sharedmutex.class-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7972)

The behavior of a program is undefined if

- [(3.1)](#thread.sharedmutex.class-3.1)

it destroys a shared_mutex object owned by any thread,

- [(3.2)](#thread.sharedmutex.class-3.2)

a thread attempts to recursively gain any ownership of a shared_mutex, or

- [(3.3)](#thread.sharedmutex.class-3.3)

a thread terminates while possessing any ownership of a shared_mutex[.](#thread.sharedmutex.class-3.sentence-1)

[4](#thread.sharedmutex.class-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7980)

shared_mutex may be a synonym for shared_timed_mutex[.](#thread.sharedmutex.class-4.sentence-1)
