1259 lines
48 KiB
Markdown
1259 lines
48 KiB
Markdown
[thread.lock]
|
||
|
||
# 32 Concurrency support library [[thread]](./#thread)
|
||
|
||
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock)
|
||
|
||
### 32.6.5 Locks [thread.lock]
|
||
|
||
#### [32.6.5.1](#general) General [[thread.lock.general]](thread.lock.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8144)
|
||
|
||
A [*lock*](#def:lock) is an object that holds a reference to a lockable object and may unlock the
|
||
lockable object during the lock's destruction (such as when leaving block scope)[.](#general-1.sentence-1)
|
||
|
||
An execution
|
||
agent may use a lock to aid in managing ownership of a lockable object in an exception safe
|
||
manner[.](#general-1.sentence-2)
|
||
|
||
A lock is said to [*own*](#def:own) a lockable object if it is currently managing the
|
||
ownership of that lockable object for an execution agent[.](#general-1.sentence-3)
|
||
|
||
A lock does not manage the lifetime
|
||
of the lockable object it references[.](#general-1.sentence-4)
|
||
|
||
[*Note [1](#general-note-1)*:
|
||
|
||
Locks are intended to ease the burden of
|
||
unlocking the lockable object under both normal and exceptional circumstances[.](#general-1.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
[2](#general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8156)
|
||
|
||
Some lock constructors take tag types which describe what should be done with the lockable
|
||
object during the lock's construction[.](#general-2.sentence-1)
|
||
|
||
[ð](#lib:defer_lock_t)
|
||
|
||
namespace std {struct defer_lock_t { }; // do not acquire ownership of the mutexstruct try_to_lock_t { }; // try to acquire ownership of the mutex// without blockingstruct adopt_lock_t { }; // assume the calling thread has already// obtained mutex ownership and manage itinline constexpr defer_lock_t defer_lock { }; inline constexpr try_to_lock_t try_to_lock { }; inline constexpr adopt_lock_t adopt_lock { };}
|
||
|
||
#### [32.6.5.2](#guard) Class template lock_guard [[thread.lock.guard]](thread.lock.guard)
|
||
|
||
[ð](#lib:lock_guard)
|
||
|
||
namespace std {template<class Mutex>class lock_guard {public:using mutex_type = Mutex; explicit lock_guard(mutex_type& m);
|
||
lock_guard(mutex_type& m, adopt_lock_t); ~lock_guard();
|
||
|
||
lock_guard(const lock_guard&) = delete;
|
||
lock_guard& operator=(const lock_guard&) = delete; private: mutex_type& pm; // *exposition only*};}
|
||
|
||
[1](#guard-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8203)
|
||
|
||
An object of type lock_guard controls the ownership of a lockable object
|
||
within a scope[.](#guard-1.sentence-1)
|
||
|
||
A lock_guard object maintains ownership of a lockable
|
||
object throughout the lock_guard object's [lifetime](basic.life#def:lifetime "6.8.4 Lifetime [basic.life]")[.](#guard-1.sentence-2)
|
||
|
||
The behavior of a program is undefined if the lockable object referenced bypm does not exist for the entire lifetime of the lock_guard object[.](#guard-1.sentence-3)
|
||
|
||
The supplied Mutex type shall meet the [*Cpp17BasicLockable*](thread.req.lockable.basic#:Cpp17BasicLockable "32.2.5.2 Cpp17BasicLockable requirements [thread.req.lockable.basic]") requirements ([[thread.req.lockable.basic]](thread.req.lockable.basic "32.2.5.2 Cpp17BasicLockable requirements"))[.](#guard-1.sentence-4)
|
||
|
||
[ð](#lib:lock_guard,constructor)
|
||
|
||
`explicit lock_guard(mutex_type& m);
|
||
`
|
||
|
||
[2](#guard-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8218)
|
||
|
||
*Effects*: Initializes pm with m[.](#guard-2.sentence-1)
|
||
|
||
Calls m.lock()[.](#guard-2.sentence-2)
|
||
|
||
[ð](#lib:lock_guard,constructor_)
|
||
|
||
`lock_guard(mutex_type& m, adopt_lock_t);
|
||
`
|
||
|
||
[3](#guard-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8229)
|
||
|
||
*Preconditions*: The calling thread holds a non-shared lock on m[.](#guard-3.sentence-1)
|
||
|
||
[4](#guard-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8233)
|
||
|
||
*Effects*: Initializes pm with m[.](#guard-4.sentence-1)
|
||
|
||
[5](#guard-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8237)
|
||
|
||
*Throws*: Nothing[.](#guard-5.sentence-1)
|
||
|
||
[ð](#lib:lock_guard,destructor)
|
||
|
||
`~lock_guard();
|
||
`
|
||
|
||
[6](#guard-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8248)
|
||
|
||
*Effects*: Equivalent to: pm.unlock()
|
||
|
||
#### [32.6.5.3](#scoped) Class template scoped_lock [[thread.lock.scoped]](thread.lock.scoped)
|
||
|
||
[ð](#lib:scoped_lock)
|
||
|
||
namespace std {template<class... MutexTypes>class scoped_lock {public:using mutex_type = *see below*; // Only if sizeof...(MutexTypes) == 1 is trueexplicit scoped_lock(MutexTypes&... m); explicit scoped_lock(adopt_lock_t, MutexTypes&... m); ~scoped_lock();
|
||
|
||
scoped_lock(const scoped_lock&) = delete;
|
||
scoped_lock& operator=(const scoped_lock&) = delete; private: tuple<MutexTypes&...> pm; // *exposition only*};}
|
||
|
||
[1](#scoped-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8276)
|
||
|
||
An object of type scoped_lock controls the ownership of lockable objects
|
||
within a scope[.](#scoped-1.sentence-1)
|
||
|
||
A scoped_lock object maintains ownership of lockable
|
||
objects throughout the scoped_lock object's [lifetime](basic.life#def:lifetime "6.8.4 Lifetime [basic.life]")[.](#scoped-1.sentence-2)
|
||
|
||
The behavior of a program is undefined if the lockable objects referenced bypm do not exist for the entire lifetime of the scoped_lock object[.](#scoped-1.sentence-3)
|
||
|
||
- [(1.1)](#scoped-1.1)
|
||
|
||
If sizeof...(MutexTypes) is one,
|
||
let Mutex denote the sole type constituting the pack MutexTypes[.](#scoped-1.1.sentence-1)
|
||
Mutex shall meet the [*Cpp17BasicLockable*](thread.req.lockable.basic#:Cpp17BasicLockable "32.2.5.2 Cpp17BasicLockable requirements [thread.req.lockable.basic]") requirements ([[thread.req.lockable.basic]](thread.req.lockable.basic "32.2.5.2 Cpp17BasicLockable requirements"))[.](#scoped-1.1.sentence-2)
|
||
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") mutex_type denotes the same type as Mutex[.](#scoped-1.1.sentence-3)
|
||
|
||
- [(1.2)](#scoped-1.2)
|
||
|
||
Otherwise, all types in the template parameter pack MutexTypes shall meet the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3 Cpp17Lockable requirements [thread.req.lockable.req]") requirements ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3 Cpp17Lockable requirements"))
|
||
and there is no member mutex_type[.](#scoped-1.2.sentence-1)
|
||
|
||
[ð](#lib:scoped_lock,constructor)
|
||
|
||
`explicit scoped_lock(MutexTypes&... m);
|
||
`
|
||
|
||
[2](#scoped-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8303)
|
||
|
||
*Effects*: Initializes pm with tie(m...)[.](#scoped-2.sentence-1)
|
||
|
||
Then if sizeof...(MutexTypes) is 0, no effects[.](#scoped-2.sentence-2)
|
||
|
||
Otherwise if sizeof...(MutexTypes) is 1, then m.lock()[.](#scoped-2.sentence-3)
|
||
|
||
Otherwise, lock(m...)[.](#scoped-2.sentence-4)
|
||
|
||
[ð](#lib:scoped_lock,constructor_)
|
||
|
||
`explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
|
||
`
|
||
|
||
[3](#scoped-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8317)
|
||
|
||
*Preconditions*: The calling thread holds a non-shared lock on each element of m[.](#scoped-3.sentence-1)
|
||
|
||
[4](#scoped-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8321)
|
||
|
||
*Effects*: Initializes pm with tie(m...)[.](#scoped-4.sentence-1)
|
||
|
||
[5](#scoped-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8325)
|
||
|
||
*Throws*: Nothing[.](#scoped-5.sentence-1)
|
||
|
||
[ð](#lib:scoped_lock,destructor)
|
||
|
||
`~scoped_lock();
|
||
`
|
||
|
||
[6](#scoped-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8336)
|
||
|
||
*Effects*: For all i in [0, sizeof...(MutexTypes)),get<i>(pm).unlock()[.](#scoped-6.sentence-1)
|
||
|
||
#### [32.6.5.4](#unique) Class template unique_lock [[thread.lock.unique]](thread.lock.unique)
|
||
|
||
#### [32.6.5.4.1](#unique.general) General [[thread.lock.unique.general]](thread.lock.unique.general)
|
||
|
||
[ð](#lib:unique_lock)
|
||
|
||
namespace std {template<class Mutex>class unique_lock {public:using mutex_type = Mutex; // [[thread.lock.unique.cons]](#unique.cons "32.6.5.4.2 Constructors, destructor, and assignment"), construct/copy/destroy unique_lock() noexcept; explicit unique_lock(mutex_type& m);
|
||
unique_lock(mutex_type& m, defer_lock_t) noexcept;
|
||
unique_lock(mutex_type& m, try_to_lock_t);
|
||
unique_lock(mutex_type& m, adopt_lock_t); template<class Clock, class Duration> unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); template<class Rep, class Period> unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); ~unique_lock();
|
||
|
||
unique_lock(const unique_lock&) = delete;
|
||
unique_lock& operator=(const unique_lock&) = delete;
|
||
|
||
unique_lock(unique_lock&& u) noexcept;
|
||
unique_lock& operator=(unique_lock&& u) noexcept; // [[thread.lock.unique.locking]](#unique.locking "32.6.5.4.3 Locking"), lockingvoid lock(); bool try_lock(); template<class Rep, class Period>bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); template<class Clock, class Duration>bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); void unlock(); // [[thread.lock.unique.mod]](#unique.mod "32.6.5.4.4 Modifiers"), modifiersvoid swap(unique_lock& u) noexcept;
|
||
mutex_type* release() noexcept; // [[thread.lock.unique.obs]](#unique.obs "32.6.5.4.5 Observers"), observersbool owns_lock() const noexcept; explicit operator bool() const noexcept;
|
||
mutex_type* mutex() const noexcept; private: mutex_type* pm; // *exposition only*bool owns; // *exposition only*};}
|
||
|
||
[1](#unique.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8399)
|
||
|
||
An object of type unique_lock controls the ownership of a lockable
|
||
object within a scope[.](#unique.general-1.sentence-1)
|
||
|
||
Ownership of the lockable object may be acquired at
|
||
construction or after construction, and may be transferred, after
|
||
acquisition, to another unique_lock object[.](#unique.general-1.sentence-2)
|
||
|
||
Objects of type unique_lock are not
|
||
copyable but are movable[.](#unique.general-1.sentence-3)
|
||
|
||
The behavior of a program is undefined if the contained pointerpm is not null and the lockable object pointed
|
||
to by pm does not exist for the entire remaining
|
||
lifetime ([[basic.life]](basic.life "6.8.4 Lifetime")) of the unique_lock object[.](#unique.general-1.sentence-4)
|
||
|
||
The suppliedMutex type shall meet the [*Cpp17BasicLockable*](thread.req.lockable.basic#:Cpp17BasicLockable "32.2.5.2 Cpp17BasicLockable requirements [thread.req.lockable.basic]") requirements ([[thread.req.lockable.basic]](thread.req.lockable.basic "32.2.5.2 Cpp17BasicLockable requirements"))[.](#unique.general-1.sentence-5)
|
||
|
||
[2](#unique.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8411)
|
||
|
||
[*Note [1](#unique.general-note-1)*:
|
||
|
||
unique_lock<Mutex> meets the [*Cpp17BasicLockable*](thread.req.lockable.basic#:Cpp17BasicLockable "32.2.5.2 Cpp17BasicLockable requirements [thread.req.lockable.basic]") requirements[.](#unique.general-2.sentence-1)
|
||
|
||
If Mutex meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3 Cpp17Lockable requirements [thread.req.lockable.req]") requirements ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3 Cpp17Lockable requirements")),unique_lock<Mutex> also meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3 Cpp17Lockable requirements [thread.req.lockable.req]") requirements;
|
||
if Mutex meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4 Cpp17TimedLockable requirements [thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4 Cpp17TimedLockable requirements")),unique_lock<Mutex> also meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4 Cpp17TimedLockable requirements [thread.req.lockable.timed]") requirements[.](#unique.general-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
#### [32.6.5.4.2](#unique.cons) Constructors, destructor, and assignment [[thread.lock.unique.cons]](thread.lock.unique.cons)
|
||
|
||
[ð](#lib:unique_lock,constructor)
|
||
|
||
`unique_lock() noexcept;
|
||
`
|
||
|
||
[1](#unique.cons-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8429)
|
||
|
||
*Postconditions*: pm == nullptr and owns == false[.](#unique.cons-1.sentence-1)
|
||
|
||
[ð](#lib:unique_lock,constructor_)
|
||
|
||
`explicit unique_lock(mutex_type& m);
|
||
`
|
||
|
||
[2](#unique.cons-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8440)
|
||
|
||
*Effects*: Calls m.lock()[.](#unique.cons-2.sentence-1)
|
||
|
||
[3](#unique.cons-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8444)
|
||
|
||
*Postconditions*: pm == addressof(m) and owns == true[.](#unique.cons-3.sentence-1)
|
||
|
||
[ð](#lib:unique_lock,constructor__)
|
||
|
||
`unique_lock(mutex_type& m, defer_lock_t) noexcept;
|
||
`
|
||
|
||
[4](#unique.cons-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8455)
|
||
|
||
*Postconditions*: pm == addressof(m) and owns == false[.](#unique.cons-4.sentence-1)
|
||
|
||
[ð](#lib:unique_lock,constructor___)
|
||
|
||
`unique_lock(mutex_type& m, try_to_lock_t);
|
||
`
|
||
|
||
[5](#unique.cons-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8466)
|
||
|
||
*Preconditions*: The supplied Mutex type meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3 Cpp17Lockable requirements [thread.req.lockable.req]") requirements ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3 Cpp17Lockable requirements"))[.](#unique.cons-5.sentence-1)
|
||
|
||
[6](#unique.cons-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8471)
|
||
|
||
*Effects*: Calls m.try_lock()[.](#unique.cons-6.sentence-1)
|
||
|
||
[7](#unique.cons-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8475)
|
||
|
||
*Postconditions*: pm == addressof(m) and owns == res,
|
||
where res is the value returned by the call to m.try_lock()[.](#unique.cons-7.sentence-1)
|
||
|
||
[ð](#lib:unique_lock,constructor____)
|
||
|
||
`unique_lock(mutex_type& m, adopt_lock_t);
|
||
`
|
||
|
||
[8](#unique.cons-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8487)
|
||
|
||
*Preconditions*: The calling thread holds a non-shared lock on m[.](#unique.cons-8.sentence-1)
|
||
|
||
[9](#unique.cons-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8491)
|
||
|
||
*Postconditions*: pm == addressof(m) and owns == true[.](#unique.cons-9.sentence-1)
|
||
|
||
[10](#unique.cons-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8495)
|
||
|
||
*Throws*: Nothing[.](#unique.cons-10.sentence-1)
|
||
|
||
[ð](#lib:unique_lock,constructor_____)
|
||
|
||
`template<class Clock, class Duration>
|
||
unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
|
||
`
|
||
|
||
[11](#unique.cons-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8507)
|
||
|
||
*Preconditions*: The supplied Mutex type meets the[*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4 Cpp17TimedLockable requirements [thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4 Cpp17TimedLockable requirements"))[.](#unique.cons-11.sentence-1)
|
||
|
||
[12](#unique.cons-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8512)
|
||
|
||
*Effects*: Calls m.try_lock_until(abs_time)[.](#unique.cons-12.sentence-1)
|
||
|
||
[13](#unique.cons-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8516)
|
||
|
||
*Postconditions*: pm == addressof(m) and owns == res,
|
||
where res is
|
||
the value returned by the call to m.try_lock_until(abs_time)[.](#unique.cons-13.sentence-1)
|
||
|
||
[ð](#lib:unique_lock,constructor______)
|
||
|
||
`template<class Rep, class Period>
|
||
unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
|
||
`
|
||
|
||
[14](#unique.cons-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8530)
|
||
|
||
*Preconditions*: The supplied Mutex type meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4 Cpp17TimedLockable requirements [thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4 Cpp17TimedLockable requirements"))[.](#unique.cons-14.sentence-1)
|
||
|
||
[15](#unique.cons-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8534)
|
||
|
||
*Effects*: Calls m.try_lock_for(rel_time)[.](#unique.cons-15.sentence-1)
|
||
|
||
[16](#unique.cons-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8538)
|
||
|
||
*Postconditions*: pm == addressof(m) and owns == res,
|
||
where res is the value returned by the call to m.try_lock_for(rel_time)[.](#unique.cons-16.sentence-1)
|
||
|
||
[ð](#lib:unique_lock,constructor_______)
|
||
|
||
`unique_lock(unique_lock&& u) noexcept;
|
||
`
|
||
|
||
[17](#unique.cons-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8550)
|
||
|
||
*Postconditions*: pm == u_p.pm and owns == u_p.owns (where u_p is the state of u just prior to this construction), u.pm == 0 and u.owns == false[.](#unique.cons-17.sentence-1)
|
||
|
||
[ð](#lib:operator=,unique_lock)
|
||
|
||
`unique_lock& operator=(unique_lock&& u) noexcept;
|
||
`
|
||
|
||
[18](#unique.cons-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8561)
|
||
|
||
*Effects*: Equivalent to: unique_lock(std::move(u)).swap(*this)
|
||
|
||
[19](#unique.cons-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8565)
|
||
|
||
*Returns*: *this[.](#unique.cons-19.sentence-1)
|
||
|
||
[ð](#lib:unique_lock,destructor)
|
||
|
||
`~unique_lock();
|
||
`
|
||
|
||
[20](#unique.cons-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8576)
|
||
|
||
*Effects*: If owns calls pm->unlock()[.](#unique.cons-20.sentence-1)
|
||
|
||
#### [32.6.5.4.3](#unique.locking) Locking [[thread.lock.unique.locking]](thread.lock.unique.locking)
|
||
|
||
[ð](#lib:lock,unique_lock)
|
||
|
||
`void lock();
|
||
`
|
||
|
||
[1](#unique.locking-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8589)
|
||
|
||
*Effects*: As if by pm->lock()[.](#unique.locking-1.sentence-1)
|
||
|
||
[2](#unique.locking-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8593)
|
||
|
||
*Postconditions*: owns == true[.](#unique.locking-2.sentence-1)
|
||
|
||
[3](#unique.locking-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8597)
|
||
|
||
*Throws*: Any exception thrown by pm->lock()[.](#unique.locking-3.sentence-1)
|
||
|
||
system_error when an exception
|
||
is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#unique.locking-3.sentence-2)
|
||
|
||
[4](#unique.locking-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8602)
|
||
|
||
*Error conditions*:
|
||
|
||
- [(4.1)](#unique.locking-4.1)
|
||
|
||
operation_not_permitted â if pm is nullptr[.](#unique.locking-4.1.sentence-1)
|
||
|
||
- [(4.2)](#unique.locking-4.2)
|
||
|
||
resource_deadlock_would_occur â if on entry owns is true[.](#unique.locking-4.2.sentence-1)
|
||
|
||
[ð](#lib:try_lock,unique_lock)
|
||
|
||
`bool try_lock();
|
||
`
|
||
|
||
[5](#unique.locking-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8617)
|
||
|
||
*Preconditions*: The supplied Mutex meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3 Cpp17Lockable requirements [thread.req.lockable.req]") requirements ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3 Cpp17Lockable requirements"))[.](#unique.locking-5.sentence-1)
|
||
|
||
[6](#unique.locking-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8622)
|
||
|
||
*Effects*: As if by pm->try_lock()[.](#unique.locking-6.sentence-1)
|
||
|
||
[7](#unique.locking-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8626)
|
||
|
||
*Postconditions*: owns == res, where res is the value returned bypm->try_lock()[.](#unique.locking-7.sentence-1)
|
||
|
||
[8](#unique.locking-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8631)
|
||
|
||
*Returns*: The value returned by pm->try_lock()[.](#unique.locking-8.sentence-1)
|
||
|
||
[9](#unique.locking-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8635)
|
||
|
||
*Throws*: Any exception thrown by pm->try_lock()[.](#unique.locking-9.sentence-1)
|
||
|
||
system_error when an exception
|
||
is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#unique.locking-9.sentence-2)
|
||
|
||
[10](#unique.locking-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8640)
|
||
|
||
*Error conditions*:
|
||
|
||
- [(10.1)](#unique.locking-10.1)
|
||
|
||
operation_not_permitted â if pm is nullptr[.](#unique.locking-10.1.sentence-1)
|
||
|
||
- [(10.2)](#unique.locking-10.2)
|
||
|
||
resource_deadlock_would_occur â if on entry owns is true[.](#unique.locking-10.2.sentence-1)
|
||
|
||
[ð](#lib:try_lock_until,unique_lock)
|
||
|
||
`template<class Clock, class Duration>
|
||
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
|
||
`
|
||
|
||
[11](#unique.locking-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8656)
|
||
|
||
*Preconditions*: The supplied Mutex type meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4 Cpp17TimedLockable requirements [thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4 Cpp17TimedLockable requirements"))[.](#unique.locking-11.sentence-1)
|
||
|
||
[12](#unique.locking-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8661)
|
||
|
||
*Effects*: As if by pm->try_lock_until(abs_time)[.](#unique.locking-12.sentence-1)
|
||
|
||
[13](#unique.locking-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8665)
|
||
|
||
*Postconditions*: owns == res, where res is the value returned bypm->try_lock_until(abs_time)[.](#unique.locking-13.sentence-1)
|
||
|
||
[14](#unique.locking-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8670)
|
||
|
||
*Returns*: The value returned by pm->try_lock_until(abs_time)[.](#unique.locking-14.sentence-1)
|
||
|
||
[15](#unique.locking-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8674)
|
||
|
||
*Throws*: Any exception thrown by pm->try_lock_until(abstime)[.](#unique.locking-15.sentence-1)
|
||
|
||
system_error when an
|
||
exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#unique.locking-15.sentence-2)
|
||
|
||
[16](#unique.locking-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8679)
|
||
|
||
*Error conditions*:
|
||
|
||
- [(16.1)](#unique.locking-16.1)
|
||
|
||
operation_not_permitted â if pm is nullptr[.](#unique.locking-16.1.sentence-1)
|
||
|
||
- [(16.2)](#unique.locking-16.2)
|
||
|
||
resource_deadlock_would_occur â if on entry owns istrue[.](#unique.locking-16.2.sentence-1)
|
||
|
||
[ð](#lib:try_lock_for,unique_lock)
|
||
|
||
`template<class Rep, class Period>
|
||
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
|
||
`
|
||
|
||
[17](#unique.locking-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8695)
|
||
|
||
*Preconditions*: The supplied Mutex type meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4 Cpp17TimedLockable requirements [thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4 Cpp17TimedLockable requirements"))[.](#unique.locking-17.sentence-1)
|
||
|
||
[18](#unique.locking-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8699)
|
||
|
||
*Effects*: As if by pm->try_lock_for(rel_time)[.](#unique.locking-18.sentence-1)
|
||
|
||
[19](#unique.locking-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8703)
|
||
|
||
*Postconditions*: owns == res, where res is the value returned by pm->try_lock_for(rel_time)[.](#unique.locking-19.sentence-1)
|
||
|
||
[20](#unique.locking-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8707)
|
||
|
||
*Returns*: The value returned by pm->try_lock_for(rel_time)[.](#unique.locking-20.sentence-1)
|
||
|
||
[21](#unique.locking-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8711)
|
||
|
||
*Throws*: Any exception thrown by pm->try_lock_for(rel_time)[.](#unique.locking-21.sentence-1)
|
||
|
||
system_error when an
|
||
exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#unique.locking-21.sentence-2)
|
||
|
||
[22](#unique.locking-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8716)
|
||
|
||
*Error conditions*:
|
||
|
||
- [(22.1)](#unique.locking-22.1)
|
||
|
||
operation_not_permitted â if pm is nullptr[.](#unique.locking-22.1.sentence-1)
|
||
|
||
- [(22.2)](#unique.locking-22.2)
|
||
|
||
resource_deadlock_would_occur â if on entry owns istrue[.](#unique.locking-22.2.sentence-1)
|
||
|
||
[ð](#lib:unlock,unique_lock)
|
||
|
||
`void unlock();
|
||
`
|
||
|
||
[23](#unique.locking-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8731)
|
||
|
||
*Effects*: As if by pm->unlock()[.](#unique.locking-23.sentence-1)
|
||
|
||
[24](#unique.locking-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8735)
|
||
|
||
*Postconditions*: owns == false[.](#unique.locking-24.sentence-1)
|
||
|
||
[25](#unique.locking-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8739)
|
||
|
||
*Throws*: system_error when
|
||
an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#unique.locking-25.sentence-1)
|
||
|
||
[26](#unique.locking-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8744)
|
||
|
||
*Error conditions*:
|
||
|
||
- [(26.1)](#unique.locking-26.1)
|
||
|
||
operation_not_permitted â if on entry owns is false[.](#unique.locking-26.sentence-1)
|
||
|
||
#### [32.6.5.4.4](#unique.mod) Modifiers [[thread.lock.unique.mod]](thread.lock.unique.mod)
|
||
|
||
[ð](#lib:swap,unique_lock)
|
||
|
||
`void swap(unique_lock& u) noexcept;
|
||
`
|
||
|
||
[1](#unique.mod-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8759)
|
||
|
||
*Effects*: Swaps the data members of *this and u[.](#unique.mod-1.sentence-1)
|
||
|
||
[ð](#lib:release,unique_lock)
|
||
|
||
`mutex_type* release() noexcept;
|
||
`
|
||
|
||
[2](#unique.mod-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8770)
|
||
|
||
*Postconditions*: pm == 0 and owns == false[.](#unique.mod-2.sentence-1)
|
||
|
||
[3](#unique.mod-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8774)
|
||
|
||
*Returns*: The previous value of pm[.](#unique.mod-3.sentence-1)
|
||
|
||
[ð](#lib:swap,unique_lock_)
|
||
|
||
`template<class Mutex>
|
||
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
|
||
`
|
||
|
||
[4](#unique.mod-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8786)
|
||
|
||
*Effects*: As if by x.swap(y)[.](#unique.mod-4.sentence-1)
|
||
|
||
#### [32.6.5.4.5](#unique.obs) Observers [[thread.lock.unique.obs]](thread.lock.unique.obs)
|
||
|
||
[ð](#lib:owns_lock,unique_lock)
|
||
|
||
`bool owns_lock() const noexcept;
|
||
`
|
||
|
||
[1](#unique.obs-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8799)
|
||
|
||
*Returns*: owns[.](#unique.obs-1.sentence-1)
|
||
|
||
[ð](#lib:operator_bool,unique_lock)
|
||
|
||
`explicit operator bool() const noexcept;
|
||
`
|
||
|
||
[2](#unique.obs-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8810)
|
||
|
||
*Returns*: owns[.](#unique.obs-2.sentence-1)
|
||
|
||
[ð](#lib:mutex,unique_lock)
|
||
|
||
`mutex_type *mutex() const noexcept;
|
||
`
|
||
|
||
[3](#unique.obs-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8821)
|
||
|
||
*Returns*: pm[.](#unique.obs-3.sentence-1)
|
||
|
||
#### [32.6.5.5](#shared) Class template shared_lock [[thread.lock.shared]](thread.lock.shared)
|
||
|
||
#### [32.6.5.5.1](#shared.general) General [[thread.lock.shared.general]](thread.lock.shared.general)
|
||
|
||
[ð](#lib:shared_lock)
|
||
|
||
namespace std {template<class Mutex>class shared_lock {public:using mutex_type = Mutex; // [[thread.lock.shared.cons]](#shared.cons "32.6.5.5.2 Constructors, destructor, and assignment"), construct/copy/destroy shared_lock() noexcept; explicit shared_lock(mutex_type& m); // blocking shared_lock(mutex_type& m, defer_lock_t) noexcept;
|
||
shared_lock(mutex_type& m, try_to_lock_t);
|
||
shared_lock(mutex_type& m, adopt_lock_t); template<class Clock, class Duration> shared_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); template<class Rep, class Period> shared_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); ~shared_lock();
|
||
|
||
shared_lock(const shared_lock&) = delete;
|
||
shared_lock& operator=(const shared_lock&) = delete;
|
||
|
||
shared_lock(shared_lock&& u) noexcept;
|
||
shared_lock& operator=(shared_lock&& u) noexcept; // [[thread.lock.shared.locking]](#shared.locking "32.6.5.5.3 Locking"), lockingvoid lock(); // blockingbool try_lock(); template<class Rep, class Period>bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); template<class Clock, class Duration>bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); void unlock(); // [[thread.lock.shared.mod]](#shared.mod "32.6.5.5.4 Modifiers"), modifiersvoid swap(shared_lock& u) noexcept;
|
||
mutex_type* release() noexcept; // [[thread.lock.shared.obs]](#shared.obs "32.6.5.5.5 Observers"), observersbool owns_lock() const noexcept; explicit operator bool() const noexcept;
|
||
mutex_type* mutex() const noexcept; private: mutex_type* pm; // *exposition only*bool owns; // *exposition only*};}
|
||
|
||
[1](#shared.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8881)
|
||
|
||
An object of type shared_lock controls the shared ownership of a
|
||
lockable object within a scope[.](#shared.general-1.sentence-1)
|
||
|
||
Shared ownership of the lockable object may be
|
||
acquired at construction or after construction, and may be transferred, after
|
||
acquisition, to another shared_lock object[.](#shared.general-1.sentence-2)
|
||
|
||
Objects of typeshared_lock are not copyable but are movable[.](#shared.general-1.sentence-3)
|
||
|
||
The behavior of a program
|
||
is undefined if the contained pointer pm is not null and the lockable
|
||
object pointed to by pm does not exist for the entire remaining
|
||
lifetime ([[basic.life]](basic.life "6.8.4 Lifetime")) of the shared_lock object[.](#shared.general-1.sentence-4)
|
||
|
||
The suppliedMutex type shall 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"))[.](#shared.general-1.sentence-5)
|
||
|
||
[2](#shared.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8893)
|
||
|
||
[*Note [1](#shared.general-note-1)*:
|
||
|
||
shared_lock<Mutex> meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3 Cpp17Lockable requirements [thread.req.lockable.req]") requirements ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3 Cpp17Lockable requirements"))[.](#shared.general-2.sentence-1)
|
||
|
||
If Mutex meets the [*Cpp17SharedTimedLockable*](thread.req.lockable.shared.timed#:Cpp17SharedTimedLockable "32.2.5.6 Cpp17SharedTimedLockable requirements [thread.req.lockable.shared.timed]") requirements ([[thread.req.lockable.shared.timed]](thread.req.lockable.shared.timed "32.2.5.6 Cpp17SharedTimedLockable requirements")),shared_lock<Mutex> also meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4 Cpp17TimedLockable requirements [thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4 Cpp17TimedLockable requirements"))[.](#shared.general-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
#### [32.6.5.5.2](#shared.cons) Constructors, destructor, and assignment [[thread.lock.shared.cons]](thread.lock.shared.cons)
|
||
|
||
[ð](#lib:shared_lock,constructor)
|
||
|
||
`shared_lock() noexcept;
|
||
`
|
||
|
||
[1](#shared.cons-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8911)
|
||
|
||
*Postconditions*: pm == nullptr and owns == false[.](#shared.cons-1.sentence-1)
|
||
|
||
[ð](#lib:shared_lock,constructor_)
|
||
|
||
`explicit shared_lock(mutex_type& m);
|
||
`
|
||
|
||
[2](#shared.cons-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8922)
|
||
|
||
*Effects*: Calls m.lock_shared()[.](#shared.cons-2.sentence-1)
|
||
|
||
[3](#shared.cons-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8926)
|
||
|
||
*Postconditions*: pm == addressof(m) and owns == true[.](#shared.cons-3.sentence-1)
|
||
|
||
[ð](#lib:shared_lock,constructor__)
|
||
|
||
`shared_lock(mutex_type& m, defer_lock_t) noexcept;
|
||
`
|
||
|
||
[4](#shared.cons-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8937)
|
||
|
||
*Postconditions*: pm == addressof(m) and owns == false[.](#shared.cons-4.sentence-1)
|
||
|
||
[ð](#lib:shared_lock,constructor___)
|
||
|
||
`shared_lock(mutex_type& m, try_to_lock_t);
|
||
`
|
||
|
||
[5](#shared.cons-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8948)
|
||
|
||
*Effects*: Calls m.try_lock_shared()[.](#shared.cons-5.sentence-1)
|
||
|
||
[6](#shared.cons-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8952)
|
||
|
||
*Postconditions*: pm == addressof(m) and owns == res where res is the
|
||
value returned by the call to m.try_lock_shared()[.](#shared.cons-6.sentence-1)
|
||
|
||
[ð](#lib:shared_lock,constructor____)
|
||
|
||
`shared_lock(mutex_type& m, adopt_lock_t);
|
||
`
|
||
|
||
[7](#shared.cons-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8965)
|
||
|
||
*Preconditions*: The calling thread holds a shared lock on m[.](#shared.cons-7.sentence-1)
|
||
|
||
[8](#shared.cons-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8969)
|
||
|
||
*Postconditions*: pm == addressof(m) and owns == true[.](#shared.cons-8.sentence-1)
|
||
|
||
[ð](#lib:shared_lock,constructor_____)
|
||
|
||
`template<class Clock, class Duration>
|
||
shared_lock(mutex_type& m,
|
||
const chrono::time_point<Clock, Duration>& abs_time);
|
||
`
|
||
|
||
[9](#shared.cons-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8982)
|
||
|
||
*Preconditions*: Mutex meets the [*Cpp17SharedTimedLockable*](thread.req.lockable.shared.timed#:Cpp17SharedTimedLockable "32.2.5.6 Cpp17SharedTimedLockable requirements [thread.req.lockable.shared.timed]") requirements ([[thread.req.lockable.shared.timed]](thread.req.lockable.shared.timed "32.2.5.6 Cpp17SharedTimedLockable requirements"))[.](#shared.cons-9.sentence-1)
|
||
|
||
[10](#shared.cons-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8987)
|
||
|
||
*Effects*: Calls m.try_lock_shared_until(abs_time)[.](#shared.cons-10.sentence-1)
|
||
|
||
[11](#shared.cons-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8991)
|
||
|
||
*Postconditions*: pm == addressof(m) and owns == res where res is the value returned by the call to m.try_lock_shared_until(abs_time)[.](#shared.cons-11.sentence-1)
|
||
|
||
[ð](#lib:shared_lock,constructor______)
|
||
|
||
`template<class Rep, class Period>
|
||
shared_lock(mutex_type& m,
|
||
const chrono::duration<Rep, Period>& rel_time);
|
||
`
|
||
|
||
[12](#shared.cons-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9006)
|
||
|
||
*Preconditions*: Mutex meets the [*Cpp17SharedTimedLockable*](thread.req.lockable.shared.timed#:Cpp17SharedTimedLockable "32.2.5.6 Cpp17SharedTimedLockable requirements [thread.req.lockable.shared.timed]") requirements ([[thread.req.lockable.shared.timed]](thread.req.lockable.shared.timed "32.2.5.6 Cpp17SharedTimedLockable requirements"))[.](#shared.cons-12.sentence-1)
|
||
|
||
[13](#shared.cons-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9011)
|
||
|
||
*Effects*: Calls m.try_lock_shared_for(rel_time)[.](#shared.cons-13.sentence-1)
|
||
|
||
[14](#shared.cons-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9015)
|
||
|
||
*Postconditions*: pm == addressof(m) and owns == res where res is
|
||
the value returned by the call to m.try_lock_shared_for(rel_time)[.](#shared.cons-14.sentence-1)
|
||
|
||
[ð](#lib:shared_lock,destructor)
|
||
|
||
`~shared_lock();
|
||
`
|
||
|
||
[15](#shared.cons-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9028)
|
||
|
||
*Effects*: If owns calls pm->unlock_shared()[.](#shared.cons-15.sentence-1)
|
||
|
||
[ð](#lib:shared_lock,constructor_______)
|
||
|
||
`shared_lock(shared_lock&& sl) noexcept;
|
||
`
|
||
|
||
[16](#shared.cons-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9039)
|
||
|
||
*Postconditions*: pm == sl_p.pm and owns == sl_p.owns (wheresl_p is the state of sl just prior to this construction),sl.pm == nullptr and sl.owns == false[.](#shared.cons-16.sentence-1)
|
||
|
||
[ð](#lib:operator=,shared_lock)
|
||
|
||
`shared_lock& operator=(shared_lock&& sl) noexcept;
|
||
`
|
||
|
||
[17](#shared.cons-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9052)
|
||
|
||
*Effects*: Equivalent to: shared_lock(std::move(sl)).swap(*this)
|
||
|
||
[18](#shared.cons-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9056)
|
||
|
||
*Returns*: *this[.](#shared.cons-18.sentence-1)
|
||
|
||
#### [32.6.5.5.3](#shared.locking) Locking [[thread.lock.shared.locking]](thread.lock.shared.locking)
|
||
|
||
[ð](#lib:lock,shared_lock)
|
||
|
||
`void lock();
|
||
`
|
||
|
||
[1](#shared.locking-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9069)
|
||
|
||
*Effects*: As if by pm->lock_shared()[.](#shared.locking-1.sentence-1)
|
||
|
||
[2](#shared.locking-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9073)
|
||
|
||
*Postconditions*: owns == true[.](#shared.locking-2.sentence-1)
|
||
|
||
[3](#shared.locking-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9077)
|
||
|
||
*Throws*: Any exception thrown by pm->lock_shared()[.](#shared.locking-3.sentence-1)
|
||
|
||
system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#shared.locking-3.sentence-2)
|
||
|
||
[4](#shared.locking-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9082)
|
||
|
||
*Error conditions*:
|
||
|
||
- [(4.1)](#shared.locking-4.1)
|
||
|
||
operation_not_permitted â if pm is nullptr[.](#shared.locking-4.1.sentence-1)
|
||
|
||
- [(4.2)](#shared.locking-4.2)
|
||
|
||
resource_deadlock_would_occur â if on entry owns istrue[.](#shared.locking-4.2.sentence-1)
|
||
|
||
[ð](#lib:try_lock,shared_lock)
|
||
|
||
`bool try_lock();
|
||
`
|
||
|
||
[5](#shared.locking-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9097)
|
||
|
||
*Effects*: As if by pm->try_lock_shared()[.](#shared.locking-5.sentence-1)
|
||
|
||
[6](#shared.locking-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9101)
|
||
|
||
*Postconditions*: owns == res, where res is the value returned by
|
||
the call to pm->try_lock_shared()[.](#shared.locking-6.sentence-1)
|
||
|
||
[7](#shared.locking-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9106)
|
||
|
||
*Returns*: The value returned by the call to pm->try_lock_shared()[.](#shared.locking-7.sentence-1)
|
||
|
||
[8](#shared.locking-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9110)
|
||
|
||
*Throws*: Any exception thrown by pm->try_lock_shared()[.](#shared.locking-8.sentence-1)
|
||
|
||
system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#shared.locking-8.sentence-2)
|
||
|
||
[9](#shared.locking-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9115)
|
||
|
||
*Error conditions*:
|
||
|
||
- [(9.1)](#shared.locking-9.1)
|
||
|
||
operation_not_permitted â if pm is nullptr[.](#shared.locking-9.1.sentence-1)
|
||
|
||
- [(9.2)](#shared.locking-9.2)
|
||
|
||
resource_deadlock_would_occur â if on entry owns istrue[.](#shared.locking-9.2.sentence-1)
|
||
|
||
[ð](#lib:try_lock_until,shared_lock)
|
||
|
||
`template<class Clock, class Duration>
|
||
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
|
||
`
|
||
|
||
[10](#shared.locking-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9131)
|
||
|
||
*Preconditions*: Mutex meets the [*Cpp17SharedTimedLockable*](thread.req.lockable.shared.timed#:Cpp17SharedTimedLockable "32.2.5.6 Cpp17SharedTimedLockable requirements [thread.req.lockable.shared.timed]") requirements ([[thread.req.lockable.shared.timed]](thread.req.lockable.shared.timed "32.2.5.6 Cpp17SharedTimedLockable requirements"))[.](#shared.locking-10.sentence-1)
|
||
|
||
[11](#shared.locking-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9136)
|
||
|
||
*Effects*: As if by pm->try_lock_shared_until(abs_time)[.](#shared.locking-11.sentence-1)
|
||
|
||
[12](#shared.locking-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9140)
|
||
|
||
*Postconditions*: owns == res, where res is the value returned by
|
||
the call to pm->try_lock_shared_until(abs_time)[.](#shared.locking-12.sentence-1)
|
||
|
||
[13](#shared.locking-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9145)
|
||
|
||
*Returns*: The value returned by the call topm->try_lock_shared_until(abs_time)[.](#shared.locking-13.sentence-1)
|
||
|
||
[14](#shared.locking-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9150)
|
||
|
||
*Throws*: Any exception thrown by pm->try_lock_shared_until(abs_time)[.](#shared.locking-14.sentence-1)
|
||
|
||
system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#shared.locking-14.sentence-2)
|
||
|
||
[15](#shared.locking-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9155)
|
||
|
||
*Error conditions*:
|
||
|
||
- [(15.1)](#shared.locking-15.1)
|
||
|
||
operation_not_permitted â if pm is nullptr[.](#shared.locking-15.1.sentence-1)
|
||
|
||
- [(15.2)](#shared.locking-15.2)
|
||
|
||
resource_deadlock_would_occur â if on entry owns istrue[.](#shared.locking-15.2.sentence-1)
|
||
|
||
[ð](#lib:try_lock_for,shared_lock)
|
||
|
||
`template<class Rep, class Period>
|
||
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
|
||
`
|
||
|
||
[16](#shared.locking-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9171)
|
||
|
||
*Preconditions*: Mutex meets the [*Cpp17SharedTimedLockable*](thread.req.lockable.shared.timed#:Cpp17SharedTimedLockable "32.2.5.6 Cpp17SharedTimedLockable requirements [thread.req.lockable.shared.timed]") requirements ([[thread.req.lockable.shared.timed]](thread.req.lockable.shared.timed "32.2.5.6 Cpp17SharedTimedLockable requirements"))[.](#shared.locking-16.sentence-1)
|
||
|
||
[17](#shared.locking-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9176)
|
||
|
||
*Effects*: As if by pm->try_lock_shared_for(rel_time)[.](#shared.locking-17.sentence-1)
|
||
|
||
[18](#shared.locking-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9180)
|
||
|
||
*Postconditions*: owns == res, where res is the value returned by the call to pm->try_lock_shared_for(rel_time)[.](#shared.locking-18.sentence-1)
|
||
|
||
[19](#shared.locking-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9184)
|
||
|
||
*Returns*: The value returned by the call to pm->try_lock_shared_for(rel_time)[.](#shared.locking-19.sentence-1)
|
||
|
||
[20](#shared.locking-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9188)
|
||
|
||
*Throws*: Any exception thrown by pm->try_lock_shared_for(rel_time)[.](#shared.locking-20.sentence-1)
|
||
|
||
system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#shared.locking-20.sentence-2)
|
||
|
||
[21](#shared.locking-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9192)
|
||
|
||
*Error conditions*:
|
||
|
||
- [(21.1)](#shared.locking-21.1)
|
||
|
||
operation_not_permitted â if pm is nullptr[.](#shared.locking-21.1.sentence-1)
|
||
|
||
- [(21.2)](#shared.locking-21.2)
|
||
|
||
resource_deadlock_would_occur â if on entry owns istrue[.](#shared.locking-21.2.sentence-1)
|
||
|
||
[ð](#lib:unlock,shared_lock)
|
||
|
||
`void unlock();
|
||
`
|
||
|
||
[22](#shared.locking-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9207)
|
||
|
||
*Effects*: As if by pm->unlock_shared()[.](#shared.locking-22.sentence-1)
|
||
|
||
[23](#shared.locking-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9211)
|
||
|
||
*Postconditions*: owns == false[.](#shared.locking-23.sentence-1)
|
||
|
||
[24](#shared.locking-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9215)
|
||
|
||
*Throws*: system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#shared.locking-24.sentence-1)
|
||
|
||
[25](#shared.locking-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9219)
|
||
|
||
*Error conditions*:
|
||
|
||
- [(25.1)](#shared.locking-25.1)
|
||
|
||
operation_not_permitted â if on entry owns isfalse[.](#shared.locking-25.sentence-1)
|
||
|
||
#### [32.6.5.5.4](#shared.mod) Modifiers [[thread.lock.shared.mod]](thread.lock.shared.mod)
|
||
|
||
[ð](#lib:swap,shared_lock)
|
||
|
||
`void swap(shared_lock& sl) noexcept;
|
||
`
|
||
|
||
[1](#shared.mod-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9235)
|
||
|
||
*Effects*: Swaps the data members of *this and sl[.](#shared.mod-1.sentence-1)
|
||
|
||
[ð](#lib:release,shared_lock)
|
||
|
||
`mutex_type* release() noexcept;
|
||
`
|
||
|
||
[2](#shared.mod-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9246)
|
||
|
||
*Postconditions*: pm == nullptr and owns == false[.](#shared.mod-2.sentence-1)
|
||
|
||
[3](#shared.mod-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9250)
|
||
|
||
*Returns*: The previous value of pm[.](#shared.mod-3.sentence-1)
|
||
|
||
[ð](#lib:swap,shared_lock_)
|
||
|
||
`template<class Mutex>
|
||
void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
|
||
`
|
||
|
||
[4](#shared.mod-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9262)
|
||
|
||
*Effects*: As if by x.swap(y)[.](#shared.mod-4.sentence-1)
|
||
|
||
#### [32.6.5.5.5](#shared.obs) Observers [[thread.lock.shared.obs]](thread.lock.shared.obs)
|
||
|
||
[ð](#lib:owns_lock,shared_lock)
|
||
|
||
`bool owns_lock() const noexcept;
|
||
`
|
||
|
||
[1](#shared.obs-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9275)
|
||
|
||
*Returns*: owns[.](#shared.obs-1.sentence-1)
|
||
|
||
[ð](#lib:operator_bool,shared_lock)
|
||
|
||
`explicit operator bool() const noexcept;
|
||
`
|
||
|
||
[2](#shared.obs-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9286)
|
||
|
||
*Returns*: owns[.](#shared.obs-2.sentence-1)
|
||
|
||
[ð](#lib:mutex,shared_lock)
|
||
|
||
`mutex_type* mutex() const noexcept;
|
||
`
|
||
|
||
[3](#shared.obs-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9297)
|
||
|
||
*Returns*: pm[.](#shared.obs-3.sentence-1)
|