[thread.lock.unique]

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

## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.unique)

### 32.6.5 Locks [[thread.lock]](thread.lock#unique)

#### 32.6.5.4 Class template unique_lock [thread.lock.unique]

#### [32.6.5.4.1](#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]](#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]](#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]](#mod "32.6.5.4.4 Modifiers"), modifiersvoid swap(unique_lock& u) noexcept;
 mutex_type* release() noexcept; // [[thread.lock.unique.obs]](#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](#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[.](#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[.](#general-1.sentence-2)

Objects of type unique_lock are not
copyable but are movable[.](#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[.](#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"))[.](#general-1.sentence-5)

[2](#general-2)

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

[*Note [1](#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[.](#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[.](#general-2.sentence-2)

â *end note*]

#### [32.6.5.4.2](#cons) Constructors, destructor, and assignment [[thread.lock.unique.cons]](thread.lock.unique.cons)

[ð](#lib:unique_lock,constructor)

`unique_lock() noexcept;
`

[1](#cons-1)

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

*Postconditions*: pm == nullptr and owns == false[.](#cons-1.sentence-1)

[ð](#lib:unique_lock,constructor_)

`explicit unique_lock(mutex_type& m);
`

[2](#cons-2)

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

*Effects*: Calls m.lock()[.](#cons-2.sentence-1)

[3](#cons-3)

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

*Postconditions*: pm == addressof(m) and owns == true[.](#cons-3.sentence-1)

[ð](#lib:unique_lock,constructor__)

`unique_lock(mutex_type& m, defer_lock_t) noexcept;
`

[4](#cons-4)

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

*Postconditions*: pm == addressof(m) and owns == false[.](#cons-4.sentence-1)

[ð](#lib:unique_lock,constructor___)

`unique_lock(mutex_type& m, try_to_lock_t);
`

[5](#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"))[.](#cons-5.sentence-1)

[6](#cons-6)

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

*Effects*: Calls m.try_lock()[.](#cons-6.sentence-1)

[7](#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()[.](#cons-7.sentence-1)

[ð](#lib:unique_lock,constructor____)

`unique_lock(mutex_type& m, adopt_lock_t);
`

[8](#cons-8)

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

*Preconditions*: The calling thread holds a non-shared lock on m[.](#cons-8.sentence-1)

[9](#cons-9)

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

*Postconditions*: pm == addressof(m) and owns == true[.](#cons-9.sentence-1)

[10](#cons-10)

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

*Throws*: Nothing[.](#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](#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"))[.](#cons-11.sentence-1)

[12](#cons-12)

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

*Effects*: Calls m.try_lock_until(abs_time)[.](#cons-12.sentence-1)

[13](#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)[.](#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](#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"))[.](#cons-14.sentence-1)

[15](#cons-15)

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

*Effects*: Calls m.try_lock_for(rel_time)[.](#cons-15.sentence-1)

[16](#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)[.](#cons-16.sentence-1)

[ð](#lib:unique_lock,constructor_______)

`unique_lock(unique_lock&& u) noexcept;
`

[17](#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[.](#cons-17.sentence-1)

[ð](#lib:operator=,unique_lock)

`unique_lock& operator=(unique_lock&& u) noexcept;
`

[18](#cons-18)

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

*Effects*: Equivalent to: unique_lock(std​::​move(u)).swap(*this)

[19](#cons-19)

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

*Returns*: *this[.](#cons-19.sentence-1)

[ð](#lib:unique_lock,destructor)

`~unique_lock();
`

[20](#cons-20)

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

*Effects*: If owns calls pm->unlock()[.](#cons-20.sentence-1)

#### [32.6.5.4.3](#locking) Locking [[thread.lock.unique.locking]](thread.lock.unique.locking)

[ð](#lib:lock,unique_lock)

`void lock();
`

[1](#locking-1)

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

*Effects*: As if by pm->lock()[.](#locking-1.sentence-1)

[2](#locking-2)

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

*Postconditions*: owns == true[.](#locking-2.sentence-1)

[3](#locking-3)

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

*Throws*: Any exception thrown by pm->lock()[.](#locking-3.sentence-1)

system_error when an exception
is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#locking-3.sentence-2)

[4](#locking-4)

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

*Error conditions*: 

- [(4.1)](#locking-4.1)

  operation_not_permitted â if pm is nullptr[.](#locking-4.1.sentence-1)

- [(4.2)](#locking-4.2)

  resource_deadlock_would_occur â if on entry owns is true[.](#locking-4.2.sentence-1)

[ð](#lib:try_lock,unique_lock)

`bool try_lock();
`

[5](#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"))[.](#locking-5.sentence-1)

[6](#locking-6)

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

*Effects*: As if by pm->try_lock()[.](#locking-6.sentence-1)

[7](#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()[.](#locking-7.sentence-1)

[8](#locking-8)

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

*Returns*: The value returned by pm->try_lock()[.](#locking-8.sentence-1)

[9](#locking-9)

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

*Throws*: Any exception thrown by pm->try_lock()[.](#locking-9.sentence-1)

system_error when an exception
is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#locking-9.sentence-2)

[10](#locking-10)

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

*Error conditions*: 

- [(10.1)](#locking-10.1)

  operation_not_permitted â if pm is nullptr[.](#locking-10.1.sentence-1)

- [(10.2)](#locking-10.2)

  resource_deadlock_would_occur â if on entry owns is true[.](#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](#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"))[.](#locking-11.sentence-1)

[12](#locking-12)

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

*Effects*: As if by pm->try_lock_until(abs_time)[.](#locking-12.sentence-1)

[13](#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)[.](#locking-13.sentence-1)

[14](#locking-14)

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

*Returns*: The value returned by pm->try_lock_until(abs_time)[.](#locking-14.sentence-1)

[15](#locking-15)

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

*Throws*: Any exception thrown by pm->try_lock_until(abstime)[.](#locking-15.sentence-1)

system_error when an
exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#locking-15.sentence-2)

[16](#locking-16)

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

*Error conditions*: 

- [(16.1)](#locking-16.1)

  operation_not_permitted â if pm is nullptr[.](#locking-16.1.sentence-1)

- [(16.2)](#locking-16.2)

  resource_deadlock_would_occur â if on entry owns istrue[.](#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](#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"))[.](#locking-17.sentence-1)

[18](#locking-18)

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

*Effects*: As if by pm->try_lock_for(rel_time)[.](#locking-18.sentence-1)

[19](#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)[.](#locking-19.sentence-1)

[20](#locking-20)

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

*Returns*: The value returned by pm->try_lock_for(rel_time)[.](#locking-20.sentence-1)

[21](#locking-21)

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

*Throws*: Any exception thrown by pm->try_lock_for(rel_time)[.](#locking-21.sentence-1)

system_error when an
exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#locking-21.sentence-2)

[22](#locking-22)

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

*Error conditions*: 

- [(22.1)](#locking-22.1)

  operation_not_permitted â if pm is nullptr[.](#locking-22.1.sentence-1)

- [(22.2)](#locking-22.2)

  resource_deadlock_would_occur â if on entry owns istrue[.](#locking-22.2.sentence-1)

[ð](#lib:unlock,unique_lock)

`void unlock();
`

[23](#locking-23)

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

*Effects*: As if by pm->unlock()[.](#locking-23.sentence-1)

[24](#locking-24)

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

*Postconditions*: owns == false[.](#locking-24.sentence-1)

[25](#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"))[.](#locking-25.sentence-1)

[26](#locking-26)

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

*Error conditions*: 

- [(26.1)](#locking-26.1)

operation_not_permitted â if on entry owns is false[.](#locking-26.sentence-1)

#### [32.6.5.4.4](#mod) Modifiers [[thread.lock.unique.mod]](thread.lock.unique.mod)

[ð](#lib:swap,unique_lock)

`void swap(unique_lock& u) noexcept;
`

[1](#mod-1)

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

*Effects*: Swaps the data members of *this and u[.](#mod-1.sentence-1)

[ð](#lib:release,unique_lock)

`mutex_type* release() noexcept;
`

[2](#mod-2)

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

*Postconditions*: pm == 0 and owns == false[.](#mod-2.sentence-1)

[3](#mod-3)

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

*Returns*: The previous value of pm[.](#mod-3.sentence-1)

[ð](#lib:swap,unique_lock_)

`template<class Mutex>
  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
`

[4](#mod-4)

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

*Effects*: As if by x.swap(y)[.](#mod-4.sentence-1)

#### [32.6.5.4.5](#obs) Observers [[thread.lock.unique.obs]](thread.lock.unique.obs)

[ð](#lib:owns_lock,unique_lock)

`bool owns_lock() const noexcept;
`

[1](#obs-1)

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

*Returns*: owns[.](#obs-1.sentence-1)

[ð](#lib:operator_bool,unique_lock)

`explicit operator bool() const noexcept;
`

[2](#obs-2)

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

*Returns*: owns[.](#obs-2.sentence-1)

[ð](#lib:mutex,unique_lock)

`mutex_type *mutex() const noexcept;
`

[3](#obs-3)

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

*Returns*: pm[.](#obs-3.sentence-1)
