This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

View File

@@ -0,0 +1,400 @@
[thread.jthread.class]
# 32 Concurrency support library [[thread]](./#thread)
## 32.4 Threads [[thread.threads]](thread.threads#thread.jthread.class)
### 32.4.4 Class jthread [thread.jthread.class]
#### [32.4.4.1](#general) General [[thread.jthread.class.general]](thread.jthread.class.general)
[1](#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[.](#general-1.sentence-1)
The functionality is the same as for
class thread ([[thread.thread.class]](thread.thread.class "32.4.3Class thread"))
with the additional abilities to provide
a stop_token ([[thread.stoptoken]](thread.stoptoken "32.3Stop tokens")) to the new thread of execution,
make stop requests, and automatically join[.](#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.2Constructors, move, and assignment"), constructors, move, and assignment jthread() noexcept; template<class F, class... Args> 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.3Members"), 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.3Native handles")// [[thread.jthread.stop]](#thread.jthread.stop "32.4.4.4Stop 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.5Specialized algorithms"), specialized algorithmsfriend void swap(jthread& lhs, jthread& rhs) noexcept; // [[thread.jthread.static]](#thread.jthread.static "32.4.4.6Static 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<class F, class... Args> 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<F> 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<decay_t<F>, F>,
- [(4.2)](#thread.jthread.cons-4.2)
(is_constructible_v<decay_t<Args>, Args> && ...), and
- [(4.3)](#thread.jthread.cons-4.3)
is_invocable_v<decay_t<F>, decay_t<Args>...> ||
is_invocable_v<decay_t<F>, stop_token, decay_t<Args>...>[.](#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>(f)), get_stop_token(), // for invoke, see [[func.invoke]](func.invoke "22.10.5invoke functions")auto(std::forward<Args>(args))...) if that expression is well-formed,
otherwiseinvoke(auto(std::forward<F>(f)), auto(std::forward<Args>(args))...) with the values produced by auto being materialized ([[conv.rval]](conv.rval "7.3.5Temporary 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.2Multi-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.2Exceptions"))[.](#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.2Exceptions"))[.](#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)

View File

@@ -0,0 +1,33 @@
[thread.jthread.class.general]
# 32 Concurrency support library [[thread]](./#thread)
## 32.4 Threads [[thread.threads]](thread.threads#thread.jthread.class.general)
### 32.4.4 Class jthread [[thread.jthread.class]](thread.jthread.class#general)
#### 32.4.4.1 General [thread.jthread.class.general]
[1](#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[.](#1.sentence-1)
The functionality is the same as for
class thread ([[thread.thread.class]](thread.thread.class "32.4.3Class thread"))
with the additional abilities to provide
a stop_token ([[thread.stoptoken]](thread.stoptoken "32.3Stop tokens")) to the new thread of execution,
make stop requests, and automatically join[.](#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.2Constructors, move, and assignment"), constructors, move, and assignment jthread() noexcept; template<class F, class... Args> 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.3Members"), 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.3Native handles")// [[thread.jthread.stop]](thread.jthread.stop "32.4.4.4Stop 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.5Specialized algorithms"), specialized algorithmsfriend void swap(jthread& lhs, jthread& rhs) noexcept; // [[thread.jthread.static]](thread.jthread.static "32.4.4.6Static members"), static membersstatic unsigned int hardware_concurrency() noexcept; private: stop_source ssource; // *exposition only*};}

View File

@@ -0,0 +1,177 @@
[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<class F, class... Args> explicit jthread(F&& f, Args&&... args);
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2001)
*Constraints*: remove_cvref_t<F> 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<decay_t<F>, F>,
- [(4.2)](#4.2)
(is_constructible_v<decay_t<Args>, Args> && ...), and
- [(4.3)](#4.3)
is_invocable_v<decay_t<F>, decay_t<Args>...> ||
is_invocable_v<decay_t<F>, stop_token, decay_t<Args>...>[.](#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>(f)), get_stop_token(), // for invoke, see [[func.invoke]](func.invoke "22.10.5invoke functions")auto(std::forward<Args>(args))...) if that expression is well-formed,
otherwiseinvoke(auto(std::forward<F>(f)), auto(std::forward<Args>(args))...) with the values produced by auto being materialized ([[conv.rval]](conv.rval "7.3.5Temporary 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)

View File

@@ -0,0 +1,143 @@
[thread.jthread.mem]
# 32 Concurrency support library [[thread]](./#thread)
## 32.4 Threads [[thread.threads]](thread.threads#thread.jthread.mem)
### 32.4.4 Class jthread [[thread.jthread.class]](thread.jthread.class#thread.jthread.mem)
#### 32.4.4.3 Members [thread.jthread.mem]
[🔗](#lib:swap,jthread)
`void swap(jthread& x) noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2131)
*Effects*: Exchanges the values of *this and x[.](#1.sentence-1)
[🔗](#lib:joinable,jthread)
`bool joinable() const noexcept;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2142)
*Returns*: get_id() != id()[.](#2.sentence-1)
[🔗](#lib:join,jthread)
`void join();
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2153)
*Effects*: Blocks until the thread represented by *this has completed[.](#3.sentence-1)
[4](#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.2Multi-threaded executions and data races"))
the corresponding successful join() return[.](#4.sentence-1)
[*Note [1](#note-1)*:
Operations on *this are not synchronized[.](#4.sentence-2)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2167)
*Postconditions*: The thread represented by *this has completed[.](#5.sentence-1)
get_id() == id()[.](#5.sentence-2)
[6](#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.2Exceptions"))[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2176)
*Error conditions*:
- [(7.1)](#7.1)
resource_deadlock_would_occur — if deadlock is detected orget_id() == this_thread::get_id()[.](#7.1.sentence-1)
- [(7.2)](#7.2)
no_such_process — if the thread is not valid[.](#7.2.sentence-1)
- [(7.3)](#7.3)
invalid_argument — if the thread is not joinable[.](#7.3.sentence-1)
[🔗](#lib:detach,jthread)
`void detach();
`
[8](#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[.](#8.sentence-1)
When detach() returns,*this no longer represents the possibly continuing thread of execution[.](#8.sentence-2)
When the thread previously represented by *this ends execution,
the implementation releases any owned resources[.](#8.sentence-3)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2203)
*Postconditions*: get_id() == id()[.](#9.sentence-1)
[10](#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.2Exceptions"))[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2211)
*Error conditions*:
- [(11.1)](#11.1)
no_such_process — if the thread is not valid[.](#11.1.sentence-1)
- [(11.2)](#11.2)
invalid_argument — if the thread is not joinable[.](#11.2.sentence-1)
[🔗](#lib:get_id,jthread)
`id get_id() const noexcept;
`
[12](#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[.](#12.sentence-1)

View File

@@ -0,0 +1,20 @@
[thread.jthread.special]
# 32 Concurrency support library [[thread]](./#thread)
## 32.4 Threads [[thread.threads]](thread.threads#thread.jthread.special)
### 32.4.4 Class jthread [[thread.jthread.class]](thread.jthread.class#thread.jthread.special)
#### 32.4.4.5 Specialized algorithms [thread.jthread.special]
[🔗](#lib:swap,jthread)
`friend void swap(jthread& x, jthread& y) noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2277)
*Effects*: Equivalent to: x.swap(y)[.](#1.sentence-1)

View File

@@ -0,0 +1,20 @@
[thread.jthread.static]
# 32 Concurrency support library [[thread]](./#thread)
## 32.4 Threads [[thread.threads]](thread.threads#thread.jthread.static)
### 32.4.4 Class jthread [[thread.jthread.class]](thread.jthread.class#thread.jthread.static)
#### 32.4.4.6 Static members [thread.jthread.static]
[🔗](#lib:hardware_concurrency,jthread)
`static unsigned int hardware_concurrency() noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2290)
*Returns*: thread::hardware_concurrency()[.](#1.sentence-1)

View File

@@ -0,0 +1,42 @@
[thread.jthread.stop]
# 32 Concurrency support library [[thread]](./#thread)
## 32.4 Threads [[thread.threads]](thread.threads#thread.jthread.stop)
### 32.4.4 Class jthread [[thread.jthread.class]](thread.jthread.class#thread.jthread.stop)
#### 32.4.4.4 Stop token handling [thread.jthread.stop]
[🔗](#lib:get_stop_source,jthread)
`stop_source get_stop_source() noexcept;
`
[1](#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](#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](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2263)
*Effects*: Equivalent to: return ssource.request_stop();