[thread.jthread.cons] # 32 Concurrency support library [[thread]](./#thread) ## 32.4 Threads [[thread.threads]](thread.threads#thread.jthread.cons) ### 32.4.4 Class jthread [[thread.jthread.class]](thread.jthread.class#thread.jthread.cons) #### 32.4.4.2 Constructors, move, and assignment [thread.jthread.cons] [🔗](#lib:jthread,constructor) `jthread() noexcept; ` [1](#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[.](#1.sentence-1) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1989) *Postconditions*: get_id() == id() is true and ssource.stop_possible() is false[.](#2.sentence-1) [🔗](#lib:jthread,constructor_) `template explicit jthread(F&& f, Args&&... args); ` [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2001) *Constraints*: remove_cvref_t is not the same type as jthread[.](#3.sentence-1) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2005) *Mandates*: The following are all true: - [(4.1)](#4.1) is_constructible_v, F>, - [(4.2)](#4.2) (is_constructible_v, Args> && ...), and - [(4.3)](#4.3) is_invocable_v, decay_t...> || is_invocable_v, stop_token, decay_t...>[.](#4.3.sentence-2) [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2014) *Effects*: Initializes ssource[.](#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[.](#5.sentence-2) Any return value from this invocation is ignored[.](#5.sentence-3) [*Note [1](#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[.](#5.sentence-4) — *end note*] If the invoke expression exits via an exception,terminate is called[.](#5.sentence-5) [6](#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[.](#6.sentence-1) [7](#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[.](#7.sentence-1) [*Note [2](#note-2)*: The calling thread can make a stop request only once, because it cannot replace this stop token[.](#7.sentence-2) — *end note*] [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2052) *Throws*: system_error if unable to start the new thread[.](#8.sentence-1) [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2056) *Error conditions*: - [(9.1)](#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[.](#9.sentence-1) [🔗](#lib:jthread,constructor__) `jthread(jthread&& x) noexcept; ` [10](#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[.](#10.sentence-1) ssource has the value of x.ssource prior to the start of construction and x.ssource.stop_possible() is false[.](#10.sentence-2) [🔗](#lib:jthread,destructor) `~jthread(); ` [11](#11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2088) *Effects*: If joinable() is true, calls request_stop() and then join()[.](#11.sentence-1) [*Note [3](#note-3)*: Operations on *this are not synchronized[.](#11.sentence-2) — *end note*] [🔗](#lib:operator=,jthread) `jthread& operator=(jthread&& x) noexcept; ` [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2103) *Effects*: If &x == this is true, there are no effects[.](#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[.](#12.sentence-2) [13](#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[.](#13.sentence-1) ssource has the value of x.ssource prior to the assignment[.](#13.sentence-2) [14](#14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2118) *Returns*: *this[.](#14.sentence-1)