[thread.threads] # 32 Concurrency support library [[thread]](./#thread) ## 32.4 Threads [thread.threads] ### [32.4.1](#general) General [[thread.threads.general]](thread.threads.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1405) [thread.threads] describes components that can be used to create and manage threads[.](#general-1.sentence-1) [*Note [1](#general-note-1)*: These threads are intended to map one-to-one with operating system threads[.](#general-1.sentence-2) — *end note*] ### [32.4.2](#thread.syn) Header synopsis [[thread.syn]](thread.syn) [🔗](#header:%3cthread%3e) #include // see [[compare.syn]](compare.syn "17.12.1 Header synopsis")namespace std {// [[thread.thread.class]](#thread.thread.class "32.4.3 Class thread"), class threadclass thread; void swap(thread& x, thread& y) noexcept; // [[thread.jthread.class]](#thread.jthread.class "32.4.4 Class jthread"), class jthreadclass jthread; // [[thread.thread.this]](#thread.thread.this "32.4.5 Namespace this_­thread"), namespace this_threadnamespace this_thread { thread::id get_id() noexcept; void yield() noexcept; templatevoid sleep_until(const chrono::time_point& abs_time); templatevoid sleep_for(const chrono::duration& rel_time); }} ### [32.4.3](#thread.thread.class) Class thread [[thread.thread.class]](thread.thread.class) #### [32.4.3.1](#thread.thread.class.general) General [[thread.thread.class.general]](thread.thread.class.general) [1](#thread.thread.class.general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1443) The class thread provides a mechanism to create a new thread of execution, to join with a thread (i.e., wait for a thread to complete), and to perform other operations that manage and query the state of a thread[.](#thread.thread.class.general-1.sentence-1) A thread object uniquely represents a particular thread of execution[.](#thread.thread.class.general-1.sentence-2) That representation may be transferred to other thread objects in such a way that no two thread objects simultaneously represent the same thread of execution[.](#thread.thread.class.general-1.sentence-3) A thread of execution is [*detached*](#def:detached) when no thread object represents that thread[.](#thread.thread.class.general-1.sentence-4) Objects of class thread can be in a state that does not represent a thread of execution[.](#thread.thread.class.general-1.sentence-5) [*Note [1](#thread.thread.class.general-note-1)*: A thread object does not represent a thread of execution after default construction, after being moved from, or after a successful call to detach orjoin[.](#thread.thread.class.general-1.sentence-6) — *end note*] [🔗](#lib:thread) namespace std {class thread {public:// [[thread.thread.id]](#thread.thread.id "32.4.3.2 Class thread​::​id"), class thread​::​idclass id; using native_handle_type = *implementation-defined*; // see [[thread.req.native]](thread.req.native "32.2.3 Native handles")// construct/copy/destroy thread() noexcept; template explicit thread(F&& f, Args&&... args); ~thread(); thread(const thread&) = delete; thread(thread&&) noexcept; thread& operator=(const thread&) = delete; thread& operator=(thread&&) noexcept; // [[thread.thread.member]](#thread.thread.member "32.4.3.6 Members"), membersvoid swap(thread&) noexcept; bool joinable() const noexcept; void join(); void detach(); id get_id() const noexcept; native_handle_type native_handle(); // see [[thread.req.native]](thread.req.native "32.2.3 Native handles")// static membersstatic unsigned int hardware_concurrency() noexcept; };} #### [32.4.3.2](#thread.thread.id) Class thread​::​id [[thread.thread.id]](thread.thread.id) [🔗](#lib:thread::id) namespace std {class thread::id {public: id() noexcept; }; bool operator==(thread::id x, thread::id y) noexcept; strong_ordering operator<=>(thread::id x, thread::id y) noexcept; template basic_ostream&operator<<(basic_ostream& out, thread::id id); template struct formatter; // hash supporttemplate struct hash; template<> struct hash;} [1](#thread.thread.id-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1516) An object of type thread​::​id provides a unique identifier for each thread of execution and a single distinct value for all thread objects that do not represent a thread of execution ([[thread.thread.class]](#thread.thread.class "32.4.3 Class thread"))[.](#thread.thread.id-1.sentence-1) Each thread of execution has an associated thread​::​id object that is not equal to thethread​::​id object of any other thread of execution and that is not equal to the thread​::​id object of any thread object that does not represent threads of execution[.](#thread.thread.id-1.sentence-2) [2](#thread.thread.id-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1526) The [*text representation*](#def:text_representation "32.4.3.2 Class thread​::​id [thread.thread.id]") for the character type charT of an object of type thread​::​id is an unspecified sequence of charT such that, for two objects of type thread​::​id x and y, if x == y is true, the thread​::​id objects have the same text representation, and if x != y is true, the thread​::​id objects have distinct text representations[.](#thread.thread.id-2.sentence-1) [3](#thread.thread.id-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1536) thread​::​id is a trivially copyable class ([[class.prop]](class.prop "11.2 Properties of classes"))[.](#thread.thread.id-3.sentence-1) The library may reuse the value of a thread​::​id of a terminated thread that can no longer be joined[.](#thread.thread.id-3.sentence-2) [4](#thread.thread.id-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1540) [*Note [1](#thread.thread.id-note-1)*: Relational operators allow thread​::​id objects to be used as keys in associative containers[.](#thread.thread.id-4.sentence-1) — *end note*] [🔗](#lib:thread::id,constructor) `id() noexcept; ` [5](#thread.thread.id-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1552) *Postconditions*: The constructed object does not represent a thread of execution[.](#thread.thread.id-5.sentence-1) [🔗](#lib:operator==,thread::id) `bool operator==(thread::id x, thread::id y) noexcept; ` [6](#thread.thread.id-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1563) *Returns*: true only if x and y represent the same thread of execution or neither x nor y represents a thread of execution[.](#thread.thread.id-6.sentence-1) [🔗](#lib:operator%3c=%3e,thread::id) `strong_ordering operator<=>(thread::id x, thread::id y) noexcept; ` [7](#thread.thread.id-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1576) Let P(x, y) be an unspecified total ordering over thread​::​id as described in [[alg.sorting]](alg.sorting "26.8 Sorting and related operations")[.](#thread.thread.id-7.sentence-1) [8](#thread.thread.id-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1581) *Returns*: strong_ordering​::​less if P(x, y) is true[.](#thread.thread.id-8.sentence-1) Otherwise, strong_ordering​::​greater if P(y, x) is true[.](#thread.thread.id-8.sentence-2) Otherwise, strong_ordering​::​equal[.](#thread.thread.id-8.sentence-3) [🔗](#lib:operator%3c%3c,thread::id) `template basic_ostream& operator<<(basic_ostream& out, thread::id id); ` [9](#thread.thread.id-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1597) *Effects*: Inserts the text representation for charT of id intoout[.](#thread.thread.id-9.sentence-1) [10](#thread.thread.id-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1602) *Returns*: out[.](#thread.thread.id-10.sentence-1) [🔗](#lib:formatter,specializations,thread::id) `template struct formatter; ` [11](#thread.thread.id-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1613) formatter interprets *format-spec* as a *thread-id-format-spec*[.](#thread.thread.id-11.sentence-1) The syntax of format specifications is as follows: thread-id-format-spec : fill-and-alignopt widthopt [*Note [2](#thread.thread.id-note-2)*: The productions *fill-and-align* and *width* are described in [[format.string.std]](format.string.std "28.5.2.2 Standard format specifiers")[.](#thread.thread.id-11.sentence-3) — *end note*] [12](#thread.thread.id-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1628) If the *align* option is omitted it defaults to >[.](#thread.thread.id-12.sentence-1) [13](#thread.thread.id-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1631) A thread​::​id object is formatted by writing its text representation for charT to the output with additional padding and adjustments as specified by the format specifiers[.](#thread.thread.id-13.sentence-1) [🔗](#lib:hash,thread::id) `template<> struct hash; ` [14](#thread.thread.id-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1643) The specialization is enabled ([[unord.hash]](unord.hash "22.10.19 Class template hash"))[.](#thread.thread.id-14.sentence-1) #### [32.4.3.3](#thread.thread.constr) Constructors [[thread.thread.constr]](thread.thread.constr) [🔗](#lib:thread,constructor) `thread() noexcept; ` [1](#thread.thread.constr-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1655) *Effects*: The object does not represent a thread of execution[.](#thread.thread.constr-1.sentence-1) [2](#thread.thread.constr-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1659) *Postconditions*: get_id() == id()[.](#thread.thread.constr-2.sentence-1) [🔗](#lib:thread,constructor_) `template explicit thread(F&& f, Args&&... args); ` [3](#thread.thread.constr-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1670) *Constraints*: remove_cvref_t is not the same type as thread[.](#thread.thread.constr-3.sentence-1) [4](#thread.thread.constr-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1674) *Mandates*: The following are all true: - [(4.1)](#thread.thread.constr-4.1) is_constructible_v, F>, - [(4.2)](#thread.thread.constr-4.2) (is_constructible_v, Args> && ...), and - [(4.3)](#thread.thread.constr-4.3) is_invocable_v, decay_t...>[.](#thread.thread.constr-4.sentence-1) [5](#thread.thread.constr-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1683) *Effects*: The new thread of execution executesinvoke(auto(std::forward(f)), // for invoke, see [[func.invoke]](func.invoke "22.10.5 invoke functions")auto(std::forward(args))...) with the values produced by auto being materialized ([[conv.rval]](conv.rval "7.3.5 Temporary materialization conversion")) in the constructing thread[.](#thread.thread.constr-5.sentence-1) Any return value from this invocation is ignored[.](#thread.thread.constr-5.sentence-2) [*Note [1](#thread.thread.constr-note-1)*: This implies that any exceptions not thrown from the invocation of the copy of f will be thrown in the constructing thread, not the new thread[.](#thread.thread.constr-5.sentence-3) — *end note*] If the invocation of invoke terminates with an uncaught exception,terminate is invoked ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#thread.thread.constr-5.sentence-4) [6](#thread.thread.constr-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1700) *Synchronization*: The completion of the invocation of the constructor synchronizes with the beginning of the invocation of the copy of f[.](#thread.thread.constr-6.sentence-1) [7](#thread.thread.constr-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1705) *Postconditions*: get_id() != id()[.](#thread.thread.constr-7.sentence-1) *this represents the newly started thread[.](#thread.thread.constr-7.sentence-2) [8](#thread.thread.constr-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1709) *Throws*: system_error if unable to start the new thread[.](#thread.thread.constr-8.sentence-1) [9](#thread.thread.constr-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1713) *Error conditions*: - [(9.1)](#thread.thread.constr-9.1) resource_unavailable_try_again — the system lacked the necessary resources to create another thread, or the system-imposed limit on the number of threads in a process would be exceeded[.](#thread.thread.constr-9.sentence-1) [🔗](#lib:thread,constructor__) `thread(thread&& x) noexcept; ` [10](#thread.thread.constr-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1728) *Postconditions*: x.get_id() == id() and get_id() returns the value of x.get_id() prior to the start of construction[.](#thread.thread.constr-10.sentence-1) #### [32.4.3.4](#thread.thread.destr) Destructor [[thread.thread.destr]](thread.thread.destr) [🔗](#lib:thread,destructor) `~thread(); ` [1](#thread.thread.destr-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1742) *Effects*: If joinable(), invokes terminate ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#thread.thread.destr-1.sentence-1) Otherwise, has no effects[.](#thread.thread.destr-1.sentence-2) [*Note [1](#thread.thread.destr-note-1)*: Either implicitly detaching or joining a joinable() thread in its destructor can result in difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an exception is thrown[.](#thread.thread.destr-1.sentence-3) These bugs can be avoided by ensuring that the destructor is never executed while the thread is still joinable[.](#thread.thread.destr-1.sentence-4) — *end note*] #### [32.4.3.5](#thread.thread.assign) Assignment [[thread.thread.assign]](thread.thread.assign) [🔗](#lib:operator=,thread) `thread& operator=(thread&& x) noexcept; ` [1](#thread.thread.assign-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1763) *Effects*: If joinable(), invokes terminate ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#thread.thread.assign-1.sentence-1) Otherwise, assigns the state of x to *this and sets x to a default constructed state[.](#thread.thread.assign-1.sentence-2) [2](#thread.thread.assign-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1769) *Postconditions*: x.get_id() == id() and get_id() returns the value ofx.get_id() prior to the assignment[.](#thread.thread.assign-2.sentence-1) [3](#thread.thread.assign-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1774) *Returns*: *this[.](#thread.thread.assign-3.sentence-1) #### [32.4.3.6](#thread.thread.member) Members [[thread.thread.member]](thread.thread.member) [🔗](#lib:swap,thread) `void swap(thread& x) noexcept; ` [1](#thread.thread.member-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1787) *Effects*: Swaps the state of *this and x[.](#thread.thread.member-1.sentence-1) [🔗](#lib:joinable,thread) `bool joinable() const noexcept; ` [2](#thread.thread.member-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1798) *Returns*: get_id() != id()[.](#thread.thread.member-2.sentence-1) [🔗](#lib:join,thread) `void join(); ` [3](#thread.thread.member-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1809) *Effects*: Blocks until the thread represented by *this has completed[.](#thread.thread.member-3.sentence-1) [4](#thread.thread.member-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1814) *Synchronization*: The completion of the thread represented by *this synchronizes with ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races")) the corresponding successfuljoin() return[.](#thread.thread.member-4.sentence-1) [*Note [1](#thread.thread.member-note-1)*: Operations on*this are not synchronized[.](#thread.thread.member-4.sentence-2) — *end note*] [5](#thread.thread.member-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1824) *Postconditions*: The thread represented by *this has completed[.](#thread.thread.member-5.sentence-1) get_id() == id()[.](#thread.thread.member-5.sentence-2) [6](#thread.thread.member-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1828) *Throws*: system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#thread.thread.member-6.sentence-1) [7](#thread.thread.member-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1833) *Error conditions*: - [(7.1)](#thread.thread.member-7.1) resource_deadlock_would_occur — if deadlock is detected orget_id() == this_thread​::​​get_id()[.](#thread.thread.member-7.1.sentence-1) - [(7.2)](#thread.thread.member-7.2) no_such_process — if the thread is not valid[.](#thread.thread.member-7.2.sentence-1) - [(7.3)](#thread.thread.member-7.3) invalid_argument — if the thread is not joinable[.](#thread.thread.member-7.3.sentence-1) [🔗](#lib:detach,thread) `void detach(); ` [8](#thread.thread.member-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1851) *Effects*: The thread represented by *this continues execution without the calling thread blocking[.](#thread.thread.member-8.sentence-1) When detach() returns, *this no longer represents the possibly continuing thread of execution[.](#thread.thread.member-8.sentence-2) When the thread previously represented by *this ends execution, the implementation releases any owned resources[.](#thread.thread.member-8.sentence-3) [9](#thread.thread.member-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1858) *Postconditions*: get_id() == id()[.](#thread.thread.member-9.sentence-1) [10](#thread.thread.member-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1862) *Throws*: system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#thread.thread.member-10.sentence-1) [11](#thread.thread.member-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1867) *Error conditions*: - [(11.1)](#thread.thread.member-11.1) no_such_process — if the thread is not valid[.](#thread.thread.member-11.1.sentence-1) - [(11.2)](#thread.thread.member-11.2) invalid_argument — if the thread is not joinable[.](#thread.thread.member-11.2.sentence-1) [🔗](#lib:get_id,thread) `id get_id() const noexcept; ` [12](#thread.thread.member-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1881) *Returns*: A default constructed id object if *this does not represent a thread, otherwise this_thread​::​get_id() for the thread of execution represented by*this[.](#thread.thread.member-12.sentence-1) #### [32.4.3.7](#thread.thread.static) Static members [[thread.thread.static]](thread.thread.static) [🔗](#lib:hardware_concurrency,thread) `unsigned hardware_concurrency() noexcept; ` [1](#thread.thread.static-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1896) *Returns*: The number of hardware thread contexts[.](#thread.thread.static-1.sentence-1) [*Note [1](#thread.thread.static-note-1)*: This value should only be considered to be a hint[.](#thread.thread.static-1.sentence-2) — *end note*] If this value is not computable or well-defined, an implementation should return 0[.](#thread.thread.static-1.sentence-3) #### [32.4.3.8](#thread.thread.algorithm) Specialized algorithms [[thread.thread.algorithm]](thread.thread.algorithm) [🔗](#lib:swap,thread_) `void swap(thread& x, thread& y) noexcept; ` [1](#thread.thread.algorithm-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1915) *Effects*: As if by x.swap(y)[.](#thread.thread.algorithm-1.sentence-1) ### [32.4.4](#thread.jthread.class) Class jthread [[thread.jthread.class]](thread.jthread.class) #### [32.4.4.1](#thread.jthread.class.general) General [[thread.jthread.class.general]](thread.jthread.class.general) [1](#thread.jthread.class.general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1924) The class jthread provides a mechanism to create a new thread of execution[.](#thread.jthread.class.general-1.sentence-1) The functionality is the same as for class thread ([[thread.thread.class]](#thread.thread.class "32.4.3 Class thread")) with the additional abilities to provide a stop_token ([[thread.stoptoken]](thread.stoptoken "32.3 Stop tokens")) to the new thread of execution, make stop requests, and automatically join[.](#thread.jthread.class.general-1.sentence-2) [🔗](#lib:jthread) namespace std {class jthread {public:// typesusing id = thread::id; using native_handle_type = thread::native_handle_type; // [[thread.jthread.cons]](#thread.jthread.cons "32.4.4.2 Constructors, move, and assignment"), constructors, move, and assignment jthread() noexcept; template explicit jthread(F&& f, Args&&... args); ~jthread(); jthread(const jthread&) = delete; jthread(jthread&&) noexcept; jthread& operator=(const jthread&) = delete; jthread& operator=(jthread&&) noexcept; // [[thread.jthread.mem]](#thread.jthread.mem "32.4.4.3 Members"), membersvoid swap(jthread&) noexcept; bool joinable() const noexcept; void join(); void detach(); id get_id() const noexcept; native_handle_type native_handle(); // see [[thread.req.native]](thread.req.native "32.2.3 Native handles")// [[thread.jthread.stop]](#thread.jthread.stop "32.4.4.4 Stop token handling"), stop token handling stop_source get_stop_source() noexcept; stop_token get_stop_token() const noexcept; bool request_stop() noexcept; // [[thread.jthread.special]](#thread.jthread.special "32.4.4.5 Specialized algorithms"), specialized algorithmsfriend void swap(jthread& lhs, jthread& rhs) noexcept; // [[thread.jthread.static]](#thread.jthread.static "32.4.4.6 Static members"), static membersstatic unsigned int hardware_concurrency() noexcept; private: stop_source ssource; // *exposition only*};} #### [32.4.4.2](#thread.jthread.cons) Constructors, move, and assignment [[thread.jthread.cons]](thread.jthread.cons) [🔗](#lib:jthread,constructor) `jthread() noexcept; ` [1](#thread.jthread.cons-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1984) *Effects*: Constructs a jthread object that does not represent a thread of execution[.](#thread.jthread.cons-1.sentence-1) [2](#thread.jthread.cons-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1989) *Postconditions*: get_id() == id() is true and ssource.stop_possible() is false[.](#thread.jthread.cons-2.sentence-1) [🔗](#lib:jthread,constructor_) `template explicit jthread(F&& f, Args&&... args); ` [3](#thread.jthread.cons-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2001) *Constraints*: remove_cvref_t is not the same type as jthread[.](#thread.jthread.cons-3.sentence-1) [4](#thread.jthread.cons-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2005) *Mandates*: The following are all true: - [(4.1)](#thread.jthread.cons-4.1) is_constructible_v, F>, - [(4.2)](#thread.jthread.cons-4.2) (is_constructible_v, Args> && ...), and - [(4.3)](#thread.jthread.cons-4.3) is_invocable_v, decay_t...> || is_invocable_v, stop_token, decay_t...>[.](#thread.jthread.cons-4.3.sentence-2) [5](#thread.jthread.cons-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2014) *Effects*: Initializes ssource[.](#thread.jthread.cons-5.sentence-1) The new thread of execution executesinvoke(auto(std::forward(f)), get_stop_token(), // for invoke, see [[func.invoke]](func.invoke "22.10.5 invoke functions")auto(std::forward(args))...) if that expression is well-formed, otherwiseinvoke(auto(std::forward(f)), auto(std::forward(args))...) with the values produced by auto being materialized ([[conv.rval]](conv.rval "7.3.5 Temporary materialization conversion")) in the constructing thread[.](#thread.jthread.cons-5.sentence-2) Any return value from this invocation is ignored[.](#thread.jthread.cons-5.sentence-3) [*Note [1](#thread.jthread.cons-note-1)*: This implies that any exceptions not thrown from the invocation of the copy of f will be thrown in the constructing thread, not the new thread[.](#thread.jthread.cons-5.sentence-4) — *end note*] If the invoke expression exits via an exception,terminate is called[.](#thread.jthread.cons-5.sentence-5) [6](#thread.jthread.cons-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2037) *Synchronization*: The completion of the invocation of the constructor synchronizes with the beginning of the invocation of the copy of f[.](#thread.jthread.cons-6.sentence-1) [7](#thread.jthread.cons-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2042) *Postconditions*: get_id() != id() is true and ssource.stop_possible() is true and *this represents the newly started thread[.](#thread.jthread.cons-7.sentence-1) [*Note [2](#thread.jthread.cons-note-2)*: The calling thread can make a stop request only once, because it cannot replace this stop token[.](#thread.jthread.cons-7.sentence-2) — *end note*] [8](#thread.jthread.cons-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2052) *Throws*: system_error if unable to start the new thread[.](#thread.jthread.cons-8.sentence-1) [9](#thread.jthread.cons-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2056) *Error conditions*: - [(9.1)](#thread.jthread.cons-9.1) resource_unavailable_try_again — the system lacked the necessary resources to create another thread, or the system-imposed limit on the number of threads in a process would be exceeded[.](#thread.jthread.cons-9.sentence-1) [🔗](#lib:jthread,constructor__) `jthread(jthread&& x) noexcept; ` [10](#thread.jthread.cons-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2072) *Postconditions*: x.get_id() == id() and get_id() returns the value of x.get_id() prior to the start of construction[.](#thread.jthread.cons-10.sentence-1) ssource has the value of x.ssource prior to the start of construction and x.ssource.stop_possible() is false[.](#thread.jthread.cons-10.sentence-2) [🔗](#lib:jthread,destructor) `~jthread(); ` [11](#thread.jthread.cons-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2088) *Effects*: If joinable() is true, calls request_stop() and then join()[.](#thread.jthread.cons-11.sentence-1) [*Note [3](#thread.jthread.cons-note-3)*: Operations on *this are not synchronized[.](#thread.jthread.cons-11.sentence-2) — *end note*] [🔗](#lib:operator=,jthread) `jthread& operator=(jthread&& x) noexcept; ` [12](#thread.jthread.cons-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2103) *Effects*: If &x == this is true, there are no effects[.](#thread.jthread.cons-12.sentence-1) Otherwise, if joinable() is true, calls request_stop() and then join(), then assigns the state of x to *this and sets x to a default constructed state[.](#thread.jthread.cons-12.sentence-2) [13](#thread.jthread.cons-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2111) *Postconditions*: get_id() returns the value of x.get_id() prior to the assignment[.](#thread.jthread.cons-13.sentence-1) ssource has the value of x.ssource prior to the assignment[.](#thread.jthread.cons-13.sentence-2) [14](#thread.jthread.cons-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2118) *Returns*: *this[.](#thread.jthread.cons-14.sentence-1) #### [32.4.4.3](#thread.jthread.mem) Members [[thread.jthread.mem]](thread.jthread.mem) [🔗](#lib:swap,jthread) `void swap(jthread& x) noexcept; ` [1](#thread.jthread.mem-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2131) *Effects*: Exchanges the values of *this and x[.](#thread.jthread.mem-1.sentence-1) [🔗](#lib:joinable,jthread) `bool joinable() const noexcept; ` [2](#thread.jthread.mem-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2142) *Returns*: get_id() != id()[.](#thread.jthread.mem-2.sentence-1) [🔗](#lib:join,jthread) `void join(); ` [3](#thread.jthread.mem-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2153) *Effects*: Blocks until the thread represented by *this has completed[.](#thread.jthread.mem-3.sentence-1) [4](#thread.jthread.mem-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2158) *Synchronization*: The completion of the thread represented by *this synchronizes with ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races")) the corresponding successful join() return[.](#thread.jthread.mem-4.sentence-1) [*Note [1](#thread.jthread.mem-note-1)*: Operations on *this are not synchronized[.](#thread.jthread.mem-4.sentence-2) — *end note*] [5](#thread.jthread.mem-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2167) *Postconditions*: The thread represented by *this has completed[.](#thread.jthread.mem-5.sentence-1) get_id() == id()[.](#thread.jthread.mem-5.sentence-2) [6](#thread.jthread.mem-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2172) *Throws*: system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#thread.jthread.mem-6.sentence-1) [7](#thread.jthread.mem-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2176) *Error conditions*: - [(7.1)](#thread.jthread.mem-7.1) resource_deadlock_would_occur — if deadlock is detected orget_id() == this_thread​::​​get_id()[.](#thread.jthread.mem-7.1.sentence-1) - [(7.2)](#thread.jthread.mem-7.2) no_such_process — if the thread is not valid[.](#thread.jthread.mem-7.2.sentence-1) - [(7.3)](#thread.jthread.mem-7.3) invalid_argument — if the thread is not joinable[.](#thread.jthread.mem-7.3.sentence-1) [🔗](#lib:detach,jthread) `void detach(); ` [8](#thread.jthread.mem-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2194) *Effects*: The thread represented by *this continues execution without the calling thread blocking[.](#thread.jthread.mem-8.sentence-1) When detach() returns,*this no longer represents the possibly continuing thread of execution[.](#thread.jthread.mem-8.sentence-2) When the thread previously represented by *this ends execution, the implementation releases any owned resources[.](#thread.jthread.mem-8.sentence-3) [9](#thread.jthread.mem-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2203) *Postconditions*: get_id() == id()[.](#thread.jthread.mem-9.sentence-1) [10](#thread.jthread.mem-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2207) *Throws*: system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#thread.jthread.mem-10.sentence-1) [11](#thread.jthread.mem-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2211) *Error conditions*: - [(11.1)](#thread.jthread.mem-11.1) no_such_process — if the thread is not valid[.](#thread.jthread.mem-11.1.sentence-1) - [(11.2)](#thread.jthread.mem-11.2) invalid_argument — if the thread is not joinable[.](#thread.jthread.mem-11.2.sentence-1) [🔗](#lib:get_id,jthread) `id get_id() const noexcept; ` [12](#thread.jthread.mem-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2225) *Returns*: A default constructed id object if *this does not represent a thread, otherwise this_thread​::​get_id() for the thread of execution represented by *this[.](#thread.jthread.mem-12.sentence-1) #### [32.4.4.4](#thread.jthread.stop) Stop token handling [[thread.jthread.stop]](thread.jthread.stop) [🔗](#lib:get_stop_source,jthread) `stop_source get_stop_source() noexcept; ` [1](#thread.jthread.stop-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2241) *Effects*: Equivalent to: return ssource; [🔗](#lib:get_stop_token,jthread) `stop_token get_stop_token() const noexcept; ` [2](#thread.jthread.stop-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2252) *Effects*: Equivalent to: return ssource.get_token(); [🔗](#lib:request_stop,jthread) `bool request_stop() noexcept; ` [3](#thread.jthread.stop-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2263) *Effects*: Equivalent to: return ssource.request_stop(); #### [32.4.4.5](#thread.jthread.special) Specialized algorithms [[thread.jthread.special]](thread.jthread.special) [🔗](#lib:swap,jthread_) `friend void swap(jthread& x, jthread& y) noexcept; ` [1](#thread.jthread.special-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2277) *Effects*: Equivalent to: x.swap(y)[.](#thread.jthread.special-1.sentence-1) #### [32.4.4.6](#thread.jthread.static) Static members [[thread.jthread.static]](thread.jthread.static) [🔗](#lib:hardware_concurrency,jthread) `static unsigned int hardware_concurrency() noexcept; ` [1](#thread.jthread.static-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2290) *Returns*: thread​::​hardware_concurrency()[.](#thread.jthread.static-1.sentence-1) ### [32.4.5](#thread.thread.this) Namespace this_thread [[thread.thread.this]](thread.thread.this) namespace std::this_thread { thread::id get_id() noexcept; void yield() noexcept; templatevoid sleep_until(const chrono::time_point& abs_time); templatevoid sleep_for(const chrono::duration& rel_time);} [🔗](#lib:get_id,this_thread) `thread::id this_thread::get_id() noexcept; ` [1](#thread.thread.this-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2316) *Returns*: An object of type thread​::​id that uniquely identifies the current thread of execution[.](#thread.thread.this-1.sentence-1) Every invocation from this thread of execution returns the same value[.](#thread.thread.this-1.sentence-2) The object returned does not compare equal to a default-constructed thread​::​id[.](#thread.thread.this-1.sentence-3) [🔗](#lib:yield,this_thread) `void this_thread::yield() noexcept; ` [2](#thread.thread.this-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2331) *Effects*: Offers the implementation the opportunity to reschedule[.](#thread.thread.this-2.sentence-1) [3](#thread.thread.this-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2335) *Synchronization*: None[.](#thread.thread.this-3.sentence-1) [🔗](#lib:sleep_until,this_thread) `template void sleep_until(const chrono::time_point& abs_time); ` [4](#thread.thread.this-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2347) *Effects*: Blocks the calling thread for the absolute timeout ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications")) specified by abs_time[.](#thread.thread.this-4.sentence-1) [5](#thread.thread.this-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2353) *Synchronization*: None[.](#thread.thread.this-5.sentence-1) [6](#thread.thread.this-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2357) *Throws*: Timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications"))[.](#thread.thread.this-6.sentence-1) [🔗](#lib:sleep_for,this_thread) `template void sleep_for(const chrono::duration& rel_time); ` [7](#thread.thread.this-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2369) *Effects*: Blocks the calling thread for the relative timeout ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications")) specified by rel_time[.](#thread.thread.this-7.sentence-1) [8](#thread.thread.this-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2375) *Synchronization*: None[.](#thread.thread.this-8.sentence-1) [9](#thread.thread.this-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2379) *Throws*: Timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications"))[.](#thread.thread.this-9.sentence-1)