From Jason Turner

[thread.threads]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmprny_zjuw/{from.md → to.md} +339 -102
tmp/tmprny_zjuw/{from.md → to.md} RENAMED
@@ -7,15 +7,21 @@ manage threads.
7
  system threads. — *end note*]
8
 
9
  ### Header `<thread>` synopsis <a id="thread.syn">[[thread.syn]]</a>
10
 
11
  ``` cpp
 
 
 
12
  namespace std {
13
  class thread;
14
 
15
  void swap(thread& x, thread& y) noexcept;
16
 
 
 
 
17
  namespace this_thread {
18
  thread::id get_id() noexcept;
19
 
20
  void yield() noexcept;
21
  template<class Clock, class Duration>
@@ -45,33 +51,33 @@ successful call to `detach` or `join`. — *end note*]
45
 
46
  ``` cpp
47
  namespace std {
48
  class thread {
49
  public:
50
- // types:
51
  class id;
52
- using native_handle_type = implementation-defined; // See~[thread.req.native]
53
 
54
- // construct/copy/destroy:
55
  thread() noexcept;
56
  template<class F, class... Args> explicit thread(F&& f, Args&&... args);
57
  ~thread();
58
  thread(const thread&) = delete;
59
  thread(thread&&) noexcept;
60
  thread& operator=(const thread&) = delete;
61
  thread& operator=(thread&&) noexcept;
62
 
63
- // members:
64
  void swap(thread&) noexcept;
65
  bool joinable() const noexcept;
66
  void join();
67
  void detach();
68
  id get_id() const noexcept;
69
- native_handle_type native_handle(); // See~[thread.req.native]
70
 
71
- // static members:
72
- static unsigned hardware_concurrency() noexcept;
73
  };
74
  }
75
  ```
76
 
77
  #### Class `thread::id` <a id="thread.thread.id">[[thread.thread.id]]</a>
@@ -82,150 +88,129 @@ namespace std {
82
  public:
83
  id() noexcept;
84
  };
85
 
86
  bool operator==(thread::id x, thread::id y) noexcept;
87
- bool operator!=(thread::id x, thread::id y) noexcept;
88
- bool operator<(thread::id x, thread::id y) noexcept;
89
- bool operator<=(thread::id x, thread::id y) noexcept;
90
- bool operator>(thread::id x, thread::id y) noexcept;
91
- bool operator>=(thread::id x, thread::id y) noexcept;
92
 
93
  template<class charT, class traits>
94
  basic_ostream<charT, traits>&
95
  operator<<(basic_ostream<charT, traits>& out, thread::id id);
96
 
97
- // Hash support
98
  template<class T> struct hash;
99
  template<> struct hash<thread::id>;
100
  }
101
  ```
102
 
103
  An object of type `thread::id` provides a unique identifier for each
104
  thread of execution and a single distinct value for all `thread` objects
105
- that do not represent a thread of execution ([[thread.thread.class]]).
106
  Each thread of execution has an associated `thread::id` object that is
107
  not equal to the `thread::id` object of any other thread of execution
108
  and that is not equal to the `thread::id` object of any `thread` object
109
  that does not represent threads of execution.
110
 
111
- `thread::id` shall be a trivially copyable class (Clause  [[class]]).
112
- The library may reuse the value of a `thread::id` of a terminated thread
113
- that can no longer be joined.
114
 
115
  [*Note 1*: Relational operators allow `thread::id` objects to be used
116
  as keys in associative containers. — *end note*]
117
 
118
  ``` cpp
119
  id() noexcept;
120
  ```
121
 
122
- *Effects:* Constructs an object of type `id`.
123
-
124
- *Postconditions:* The constructed object does not represent a thread of
125
  execution.
126
 
127
  ``` cpp
128
  bool operator==(thread::id x, thread::id y) noexcept;
129
  ```
130
 
131
  *Returns:* `true` only if `x` and `y` represent the same thread of
132
  execution or neither `x` nor `y` represents a thread of execution.
133
 
134
  ``` cpp
135
- bool operator!=(thread::id x, thread::id y) noexcept;
136
  ```
137
 
138
- *Returns:* `!(x == y)`
 
139
 
140
- ``` cpp
141
- bool operator<(thread::id x, thread::id y) noexcept;
142
- ```
143
-
144
- *Returns:* A value such that `operator<` is a total ordering as
145
- described in  [[alg.sorting]].
146
-
147
- ``` cpp
148
- bool operator<=(thread::id x, thread::id y) noexcept;
149
- ```
150
-
151
- *Returns:* `!(y < x)`.
152
-
153
- ``` cpp
154
- bool operator>(thread::id x, thread::id y) noexcept;
155
- ```
156
-
157
- *Returns:* `y < x`.
158
-
159
- ``` cpp
160
- bool operator>=(thread::id x, thread::id y) noexcept;
161
- ```
162
-
163
- *Returns:* `!(x < y)`.
164
 
165
  ``` cpp
166
  template<class charT, class traits>
167
  basic_ostream<charT, traits>&
168
  operator<< (basic_ostream<charT, traits>& out, thread::id id);
169
  ```
170
 
171
  *Effects:* Inserts an unspecified text representation of `id` into
172
  `out`. For two objects of type `thread::id` `x` and `y`, if `x == y` the
173
- `thread::id` objects shall have the same text representation and if
174
- `x != y` the `thread::id` objects shall have distinct text
175
- representations.
176
 
177
  *Returns:* `out`.
178
 
179
  ``` cpp
180
  template<> struct hash<thread::id>;
181
  ```
182
 
183
- The specialization is enabled ([[unord.hash]]).
184
 
185
- #### `thread` constructors <a id="thread.thread.constr">[[thread.thread.constr]]</a>
186
 
187
  ``` cpp
188
  thread() noexcept;
189
  ```
190
 
191
- *Effects:* Constructs a `thread` object that does not represent a thread
192
- of execution.
193
 
194
- *Postconditions:* `get_id() == id()`.
195
 
196
  ``` cpp
197
  template<class F, class... Args> explicit thread(F&& f, Args&&... args);
198
  ```
199
 
200
- *Requires:*  `F` and each `Ti` in `Args` shall satisfy the
201
- `MoveConstructible` requirements.
202
- ` `*`INVOKE`*`( `*`DECAY_COPY`*`( std::forward<F>(f)), `*`DECAY_COPY`*`( std::forward<Args>(args))...)` ([[func.require]])
203
- shall be a valid expression.
204
-
205
- *Remarks:* This constructor shall not participate in overload resolution
206
- if `decay_t<F>` is the same type as `std::thread`.
207
-
208
- *Effects:*  Constructs an object of type `thread`. The new thread of
209
- execution executes
210
- ` `*`INVOKE`*`( `*`DECAY_COPY`*`( std::forward<F>(f)), `*`DECAY_COPY`*`( std::forward<Args>(args))...)`
211
- with the calls to *`DECAY_COPY`* being evaluated in the constructing
 
 
 
 
 
 
 
 
212
  thread. Any return value from this invocation is ignored.
213
 
214
  [*Note 1*: This implies that any exceptions not thrown from the
215
  invocation of the copy of `f` will be thrown in the constructing thread,
216
  not the new thread. — *end note*]
217
 
218
- If the invocation of
219
- ` `*`INVOKE`*`( `*`DECAY_COPY`*`( std::forward<F>(f)), `*`DECAY_COPY`*`( std::forward<Args>(args))...)`
220
- terminates with an uncaught exception, `terminate` shall be called.
221
 
222
  *Synchronization:* The completion of the invocation of the constructor
223
  synchronizes with the beginning of the invocation of the copy of `f`.
224
 
225
- *Postconditions:* `get_id() != id()`. `*this` represents the newly
226
- started thread.
227
 
228
  *Throws:* `system_error` if unable to start the new thread.
229
 
230
  *Error conditions:*
231
 
@@ -235,45 +220,43 @@ started thread.
235
 
236
  ``` cpp
237
  thread(thread&& x) noexcept;
238
  ```
239
 
240
- *Effects:* Constructs an object of type `thread` from `x`, and sets `x`
241
- to a default constructed state.
242
 
243
- *Postconditions:* `x.get_id() == id()` and `get_id()` returns the value
244
- of `x.get_id()` prior to the start of construction.
245
-
246
- #### `thread` destructor <a id="thread.thread.destr">[[thread.thread.destr]]</a>
247
 
248
  ``` cpp
249
  ~thread();
250
  ```
251
 
252
- If `joinable()`, calls `terminate()`. Otherwise, has no effects.
 
253
 
254
  [*Note 1*: Either implicitly detaching or joining a `joinable()` thread
255
  in its destructor could result in difficult to debug correctness (for
256
  detach) or performance (for join) bugs encountered only when an
257
  exception is thrown. Thus the programmer must ensure that the destructor
258
  is never executed while the thread is still joinable. — *end note*]
259
 
260
- #### `thread` assignment <a id="thread.thread.assign">[[thread.thread.assign]]</a>
261
 
262
  ``` cpp
263
  thread& operator=(thread&& x) noexcept;
264
  ```
265
 
266
  *Effects:* If `joinable()`, calls `terminate()`. Otherwise, assigns the
267
  state of `x` to `*this` and sets `x` to a default constructed state.
268
 
269
- *Postconditions:* `x.get_id() == id()` and `get_id()` returns the value
270
- of `x.get_id()` prior to the assignment.
271
 
272
  *Returns:* `*this`.
273
 
274
- #### `thread` members <a id="thread.thread.member">[[thread.thread.member]]</a>
275
 
276
  ``` cpp
277
  void swap(thread& x) noexcept;
278
  ```
279
 
@@ -287,24 +270,23 @@ bool joinable() const noexcept;
287
 
288
  ``` cpp
289
  void join();
290
  ```
291
 
292
- *Effects:*  Blocks until the thread represented by `*this` has
293
- completed.
294
 
295
  *Synchronization:* The completion of the thread represented by `*this`
296
- synchronizes with ([[intro.multithread]]) the corresponding successful
297
  `join()` return.
298
 
299
  [*Note 1*: Operations on `*this` are not synchronized. — *end note*]
300
 
301
- *Postconditions:* The thread represented by `*this` has completed.
302
  `get_id() == id()`.
303
 
304
  *Throws:* `system_error` when an exception is
305
- required ([[thread.req.exception]]).
306
 
307
  *Error conditions:*
308
 
309
  - `resource_deadlock_would_occur` — if deadlock is detected or
310
  `get_id() == this_thread::get_id()`.
@@ -317,16 +299,16 @@ void detach();
317
 
318
  *Effects:* The thread represented by `*this` continues execution without
319
  the calling thread blocking. When `detach()` returns, `*this` no longer
320
  represents the possibly continuing thread of execution. When the thread
321
  previously represented by `*this` ends execution, the implementation
322
- shall release any owned resources.
323
 
324
- *Postconditions:* `get_id() == id()`.
325
 
326
  *Throws:* `system_error` when an exception is
327
- required ([[thread.req.exception]]).
328
 
329
  *Error conditions:*
330
 
331
  - `no_such_process` — if the thread is not valid.
332
  - `invalid_argument` — if the thread is not joinable.
@@ -337,32 +319,288 @@ id get_id() const noexcept;
337
 
338
  *Returns:* A default constructed `id` object if `*this` does not
339
  represent a thread, otherwise `this_thread::get_id()` for the thread of
340
  execution represented by `*this`.
341
 
342
- #### `thread` static members <a id="thread.thread.static">[[thread.thread.static]]</a>
343
 
344
  ``` cpp
345
  unsigned hardware_concurrency() noexcept;
346
  ```
347
 
348
  *Returns:* The number of hardware thread contexts.
349
 
350
  [*Note 1*: This value should only be considered to be a
351
  hint. — *end note*]
352
 
353
- If this value is not computable or well defined an implementation should
354
- return 0.
355
 
356
- #### `thread` specialized algorithms <a id="thread.thread.algorithm">[[thread.thread.algorithm]]</a>
357
 
358
  ``` cpp
359
  void swap(thread& x, thread& y) noexcept;
360
  ```
361
 
362
  *Effects:* As if by `x.swap(y)`.
363
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
  ### Namespace `this_thread` <a id="thread.thread.this">[[thread.thread.this]]</a>
365
 
366
  ``` cpp
367
  namespace std::this_thread {
368
  thread::id get_id() noexcept;
@@ -378,14 +616,13 @@ namespace std::this_thread {
378
  ``` cpp
379
  thread::id this_thread::get_id() noexcept;
380
  ```
381
 
382
  *Returns:* An object of type `thread::id` that uniquely identifies the
383
- current thread of execution. No other thread of execution shall have
384
- this id and this thread of execution shall always have this id. The
385
- object returned shall not compare equal to a default constructed
386
- `thread::id`.
387
 
388
  ``` cpp
389
  void this_thread::yield() noexcept;
390
  ```
391
 
@@ -397,23 +634,23 @@ void this_thread::yield() noexcept;
397
  template<class Clock, class Duration>
398
  void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
399
  ```
400
 
401
  *Effects:* Blocks the calling thread for the absolute
402
- timeout ([[thread.req.timing]]) specified by `abs_time`.
403
 
404
  *Synchronization:* None.
405
 
406
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
407
 
408
  ``` cpp
409
  template<class Rep, class Period>
410
  void sleep_for(const chrono::duration<Rep, Period>& rel_time);
411
  ```
412
 
413
  *Effects:* Blocks the calling thread for the relative
414
- timeout ([[thread.req.timing]]) specified by `rel_time`.
415
 
416
  *Synchronization:* None.
417
 
418
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
419
 
 
7
  system threads. — *end note*]
8
 
9
  ### Header `<thread>` synopsis <a id="thread.syn">[[thread.syn]]</a>
10
 
11
  ``` cpp
12
+ #include <compare> // see [compare.syn]
13
+ #include <initializer_list> // see [initializer.list.syn]
14
+
15
  namespace std {
16
  class thread;
17
 
18
  void swap(thread& x, thread& y) noexcept;
19
 
20
+ // [thread.jthread.class] class jthread
21
+ class jthread;
22
+
23
  namespace this_thread {
24
  thread::id get_id() noexcept;
25
 
26
  void yield() noexcept;
27
  template<class Clock, class Duration>
 
51
 
52
  ``` cpp
53
  namespace std {
54
  class thread {
55
  public:
56
+ // types
57
  class id;
58
+ using native_handle_type = implementation-defined; // see~[thread.req.native]
59
 
60
+ // construct/copy/destroy
61
  thread() noexcept;
62
  template<class F, class... Args> explicit thread(F&& f, Args&&... args);
63
  ~thread();
64
  thread(const thread&) = delete;
65
  thread(thread&&) noexcept;
66
  thread& operator=(const thread&) = delete;
67
  thread& operator=(thread&&) noexcept;
68
 
69
+ // members
70
  void swap(thread&) noexcept;
71
  bool joinable() const noexcept;
72
  void join();
73
  void detach();
74
  id get_id() const noexcept;
75
+ native_handle_type native_handle(); // see~[thread.req.native]
76
 
77
+ // static members
78
+ static unsigned int hardware_concurrency() noexcept;
79
  };
80
  }
81
  ```
82
 
83
  #### Class `thread::id` <a id="thread.thread.id">[[thread.thread.id]]</a>
 
88
  public:
89
  id() noexcept;
90
  };
91
 
92
  bool operator==(thread::id x, thread::id y) noexcept;
93
+ strong_ordering operator<=>(thread::id x, thread::id y) noexcept;
 
 
 
 
94
 
95
  template<class charT, class traits>
96
  basic_ostream<charT, traits>&
97
  operator<<(basic_ostream<charT, traits>& out, thread::id id);
98
 
99
+ // hash support
100
  template<class T> struct hash;
101
  template<> struct hash<thread::id>;
102
  }
103
  ```
104
 
105
  An object of type `thread::id` provides a unique identifier for each
106
  thread of execution and a single distinct value for all `thread` objects
107
+ that do not represent a thread of execution [[thread.thread.class]].
108
  Each thread of execution has an associated `thread::id` object that is
109
  not equal to the `thread::id` object of any other thread of execution
110
  and that is not equal to the `thread::id` object of any `thread` object
111
  that does not represent threads of execution.
112
 
113
+ `thread::id` is a trivially copyable class [[class.prop]]. The library
114
+ may reuse the value of a `thread::id` of a terminated thread that can no
115
+ longer be joined.
116
 
117
  [*Note 1*: Relational operators allow `thread::id` objects to be used
118
  as keys in associative containers. — *end note*]
119
 
120
  ``` cpp
121
  id() noexcept;
122
  ```
123
 
124
+ *Ensures:* The constructed object does not represent a thread of
 
 
125
  execution.
126
 
127
  ``` cpp
128
  bool operator==(thread::id x, thread::id y) noexcept;
129
  ```
130
 
131
  *Returns:* `true` only if `x` and `y` represent the same thread of
132
  execution or neither `x` nor `y` represents a thread of execution.
133
 
134
  ``` cpp
135
+ strong_ordering operator<=>(thread::id x, thread::id y) noexcept;
136
  ```
137
 
138
+ Let P(`x`, `y`) be an unspecified total ordering over `thread::id` as
139
+ described in [[alg.sorting]].
140
 
141
+ *Returns:* `strong_ordering::less` if P(`x`, `y`) is `true`. Otherwise,
142
+ `strong_ordering::greater` if P(`y`, `x`) is `true`. Otherwise,
143
+ `strong_ordering::equal`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
145
  ``` cpp
146
  template<class charT, class traits>
147
  basic_ostream<charT, traits>&
148
  operator<< (basic_ostream<charT, traits>& out, thread::id id);
149
  ```
150
 
151
  *Effects:* Inserts an unspecified text representation of `id` into
152
  `out`. For two objects of type `thread::id` `x` and `y`, if `x == y` the
153
+ `thread::id` objects have the same text representation and if `x != y`
154
+ the `thread::id` objects have distinct text representations.
 
155
 
156
  *Returns:* `out`.
157
 
158
  ``` cpp
159
  template<> struct hash<thread::id>;
160
  ```
161
 
162
+ The specialization is enabled [[unord.hash]].
163
 
164
+ #### Constructors <a id="thread.thread.constr">[[thread.thread.constr]]</a>
165
 
166
  ``` cpp
167
  thread() noexcept;
168
  ```
169
 
170
+ *Effects:* The object does not represent a thread of execution.
 
171
 
172
+ *Ensures:* `get_id() == id()`.
173
 
174
  ``` cpp
175
  template<class F, class... Args> explicit thread(F&& f, Args&&... args);
176
  ```
177
 
178
+ *Constraints:* `remove_cvref_t<F>` is not the same type as `thread`.
179
+
180
+ *Mandates:* The following are all `true`:
181
+
182
+ - `is_constructible_v<decay_t<F>, F>`,
183
+ - `(is_constructible_v<decay_t<Args>, Args> && ...)`,
184
+ - `is_move_constructible_v<decay_t<F>>`,
185
+ - `(is_move_constructible_v<decay_t<Args>> && ...)`, and
186
+ - `is_invocable_v<decay_t<F>, decay_t<Args>...>`.
187
+
188
+ *Preconditions:* `decay_t<F>` and each type in `decay_t<Args>` meet the
189
+ *Cpp17MoveConstructible* requirements.
190
+
191
+ *Effects:* The new thread of execution executes
192
+
193
+ ``` cpp
194
+ invoke(decay-copy(std::forward<F>(f)), decay-copy(std::forward<Args>(args))...)
195
+ ```
196
+
197
+ with the calls to *`decay-copy`* being evaluated in the constructing
198
  thread. Any return value from this invocation is ignored.
199
 
200
  [*Note 1*: This implies that any exceptions not thrown from the
201
  invocation of the copy of `f` will be thrown in the constructing thread,
202
  not the new thread. — *end note*]
203
 
204
+ If the invocation of `invoke` terminates with an uncaught exception,
205
+ `terminate` is called.
 
206
 
207
  *Synchronization:* The completion of the invocation of the constructor
208
  synchronizes with the beginning of the invocation of the copy of `f`.
209
 
210
+ *Ensures:* `get_id() != id()`. `*this` represents the newly started
211
+ thread.
212
 
213
  *Throws:* `system_error` if unable to start the new thread.
214
 
215
  *Error conditions:*
216
 
 
220
 
221
  ``` cpp
222
  thread(thread&& x) noexcept;
223
  ```
224
 
225
+ *Ensures:* `x.get_id() == id()` and `get_id()` returns the value of
226
+ `x.get_id()` prior to the start of construction.
227
 
228
+ #### Destructor <a id="thread.thread.destr">[[thread.thread.destr]]</a>
 
 
 
229
 
230
  ``` cpp
231
  ~thread();
232
  ```
233
 
234
+ *Effects:* If `joinable()`, calls `terminate()`. Otherwise, has no
235
+ effects.
236
 
237
  [*Note 1*: Either implicitly detaching or joining a `joinable()` thread
238
  in its destructor could result in difficult to debug correctness (for
239
  detach) or performance (for join) bugs encountered only when an
240
  exception is thrown. Thus the programmer must ensure that the destructor
241
  is never executed while the thread is still joinable. — *end note*]
242
 
243
+ #### Assignment <a id="thread.thread.assign">[[thread.thread.assign]]</a>
244
 
245
  ``` cpp
246
  thread& operator=(thread&& x) noexcept;
247
  ```
248
 
249
  *Effects:* If `joinable()`, calls `terminate()`. Otherwise, assigns the
250
  state of `x` to `*this` and sets `x` to a default constructed state.
251
 
252
+ *Ensures:* `x.get_id() == id()` and `get_id()` returns the value of
253
+ `x.get_id()` prior to the assignment.
254
 
255
  *Returns:* `*this`.
256
 
257
+ #### Members <a id="thread.thread.member">[[thread.thread.member]]</a>
258
 
259
  ``` cpp
260
  void swap(thread& x) noexcept;
261
  ```
262
 
 
270
 
271
  ``` cpp
272
  void join();
273
  ```
274
 
275
+ *Effects:* Blocks until the thread represented by `*this` has completed.
 
276
 
277
  *Synchronization:* The completion of the thread represented by `*this`
278
+ synchronizes with [[intro.multithread]] the corresponding successful
279
  `join()` return.
280
 
281
  [*Note 1*: Operations on `*this` are not synchronized. — *end note*]
282
 
283
+ *Ensures:* The thread represented by `*this` has completed.
284
  `get_id() == id()`.
285
 
286
  *Throws:* `system_error` when an exception is
287
+ required [[thread.req.exception]].
288
 
289
  *Error conditions:*
290
 
291
  - `resource_deadlock_would_occur` — if deadlock is detected or
292
  `get_id() == this_thread::get_id()`.
 
299
 
300
  *Effects:* The thread represented by `*this` continues execution without
301
  the calling thread blocking. When `detach()` returns, `*this` no longer
302
  represents the possibly continuing thread of execution. When the thread
303
  previously represented by `*this` ends execution, the implementation
304
+ releases any owned resources.
305
 
306
+ *Ensures:* `get_id() == id()`.
307
 
308
  *Throws:* `system_error` when an exception is
309
+ required [[thread.req.exception]].
310
 
311
  *Error conditions:*
312
 
313
  - `no_such_process` — if the thread is not valid.
314
  - `invalid_argument` — if the thread is not joinable.
 
319
 
320
  *Returns:* A default constructed `id` object if `*this` does not
321
  represent a thread, otherwise `this_thread::get_id()` for the thread of
322
  execution represented by `*this`.
323
 
324
+ #### Static members <a id="thread.thread.static">[[thread.thread.static]]</a>
325
 
326
  ``` cpp
327
  unsigned hardware_concurrency() noexcept;
328
  ```
329
 
330
  *Returns:* The number of hardware thread contexts.
331
 
332
  [*Note 1*: This value should only be considered to be a
333
  hint. — *end note*]
334
 
335
+ If this value is not computable or well-defined, an implementation
336
+ should return 0.
337
 
338
+ #### Specialized algorithms <a id="thread.thread.algorithm">[[thread.thread.algorithm]]</a>
339
 
340
  ``` cpp
341
  void swap(thread& x, thread& y) noexcept;
342
  ```
343
 
344
  *Effects:* As if by `x.swap(y)`.
345
 
346
+ ### Class `jthread` <a id="thread.jthread.class">[[thread.jthread.class]]</a>
347
+
348
+ The class `jthread` provides a mechanism to create a new thread of
349
+ execution. The functionality is the same as for class `thread`
350
+ [[thread.thread.class]] with the additional abilities to provide a
351
+ `stop_token` [[thread.stoptoken]] to the new thread of execution, make
352
+ stop requests, and automatically join.
353
+
354
+ ``` cpp
355
+ namespace std {
356
+ class jthread {
357
+ public:
358
+ // types
359
+ using id = thread::id;
360
+ using native_handle_type = thread::native_handle_type;
361
+
362
+ // [thread.jthread.cons], constructors, move, and assignment
363
+ jthread() noexcept;
364
+ template<class F, class... Args> explicit jthread(F&& f, Args&&... args);
365
+ ~jthread();
366
+ jthread(const jthread&) = delete;
367
+ jthread(jthread&&) noexcept;
368
+ jthread& operator=(const jthread&) = delete;
369
+ jthread& operator=(jthread&&) noexcept;
370
+
371
+ // [thread.jthread.mem], members
372
+ void swap(jthread&) noexcept;
373
+ [[nodiscard]] bool joinable() const noexcept;
374
+ void join();
375
+ void detach();
376
+ [[nodiscard]] id get_id() const noexcept;
377
+ [[nodiscard]] native_handle_type native_handle(); // see~[thread.req.native]
378
+
379
+ // [thread.jthread.stop], stop token handling
380
+ [[nodiscard]] stop_source get_stop_source() noexcept;
381
+ [[nodiscard]] stop_token get_stop_token() const noexcept;
382
+ bool request_stop() noexcept;
383
+
384
+ // [thread.jthread.special], specialized algorithms
385
+ friend void swap(jthread& lhs, jthread& rhs) noexcept;
386
+
387
+ // [thread.jthread.static], static members
388
+ [[nodiscard]] static unsigned int hardware_concurrency() noexcept;
389
+
390
+ private:
391
+ stop_source ssource; // exposition only
392
+ };
393
+ }
394
+ ```
395
+
396
+ #### Constructors, move, and assignment <a id="thread.jthread.cons">[[thread.jthread.cons]]</a>
397
+
398
+ ``` cpp
399
+ jthread() noexcept;
400
+ ```
401
+
402
+ *Effects:* Constructs a `jthread` object that does not represent a
403
+ thread of execution.
404
+
405
+ *Ensures:* `get_id() == id()` is `true` and `ssource.stop_possible()` is
406
+ `false`.
407
+
408
+ ``` cpp
409
+ template<class F, class... Args> explicit jthread(F&& f, Args&&... args);
410
+ ```
411
+
412
+ *Constraints:* `remove_cvref_t<F>` is not the same type as `jthread`.
413
+
414
+ *Mandates:* The following are all `true`:
415
+
416
+ - `is_constructible_v<decay_t<F>, F>`,
417
+ - `(is_constructible_v<decay_t<Args>, Args> && ...)`,
418
+ - `is_move_constructible_v<decay_t<F>>`,
419
+ - `(is_move_constructible_v<decay_t<Args>> && ...)`, and
420
+ - `is_invocable_v<decay_t<F>, decay_t<Args>...> ||`
421
+ `is_invocable_v<decay_t<F>, stop_token, decay_t<Args>...>`.
422
+
423
+ *Preconditions:* `decay_t<F>` and each type in `decay_t<Args>` meet the
424
+ *Cpp17MoveConstructible* requirements.
425
+
426
+ *Effects:* Initializes `ssource`. The new thread of execution executes
427
+
428
+ ``` cpp
429
+ invoke(decay-copy(std::forward<F>(f)), get_stop_token(),
430
+ decay-copy(std::forward<Args>(args))...)
431
+ ```
432
+
433
+ if that expression is well-formed, otherwise
434
+
435
+ ``` cpp
436
+ invoke(decay-copy(std::forward<F>(f)), decay-copy(std::forward<Args>(args))...)
437
+ ```
438
+
439
+ with the calls to *`decay-copy`* being evaluated in the constructing
440
+ thread. Any return value from this invocation is ignored.
441
+
442
+ [*Note 1*: This implies that any exceptions not thrown from the
443
+ invocation of the copy of `f` will be thrown in the constructing thread,
444
+ not the new thread. — *end note*]
445
+
446
+ If the `invoke` expression exits via an exception, `terminate` is
447
+ called.
448
+
449
+ *Synchronization:* The completion of the invocation of the constructor
450
+ synchronizes with the beginning of the invocation of the copy of `f`.
451
+
452
+ *Ensures:* `get_id() != id()` is `true` and `ssource.stop_possible()` is
453
+ `true` and `*this` represents the newly started thread.
454
+
455
+ [*Note 2*: The calling thread can make a stop request only once,
456
+ because it cannot replace this stop token. — *end note*]
457
+
458
+ *Throws:* `system_error` if unable to start the new thread.
459
+
460
+ *Error conditions:*
461
+
462
+ - `resource_unavailable_try_again` — the system lacked the necessary
463
+ resources to create another thread, or the system-imposed limit on the
464
+ number of threads in a process would be exceeded.
465
+
466
+ ``` cpp
467
+ jthread(jthread&& x) noexcept;
468
+ ```
469
+
470
+ *Ensures:* `x.get_id() == id()` and `get_id()` returns the value of
471
+ `x.get_id()` prior to the start of construction. `ssource` has the value
472
+ of `x.ssource` prior to the start of construction and
473
+ `x.ssource.stop_possible()` is `false`.
474
+
475
+ ``` cpp
476
+ ~jthread();
477
+ ```
478
+
479
+ *Effects:* If `joinable()` is `true`, calls `request_stop()` and then
480
+ `join()`.
481
+
482
+ [*Note 3*: Operations on `*this` are not synchronized. — *end note*]
483
+
484
+ ``` cpp
485
+ jthread& operator=(jthread&& x) noexcept;
486
+ ```
487
+
488
+ *Effects:* If `joinable()` is `true`, calls `request_stop()` and then
489
+ `join()`. Assigns the state of `x` to `*this` and sets `x` to a default
490
+ constructed state.
491
+
492
+ *Ensures:* `x.get_id() == id()` and `get_id()` returns the value of
493
+ `x.get_id()` prior to the assignment. `ssource` has the value of
494
+ `x.ssource` prior to the assignment and `x.ssource.stop_possible()` is
495
+ `false`.
496
+
497
+ *Returns:* `*this`.
498
+
499
+ #### Members <a id="thread.jthread.mem">[[thread.jthread.mem]]</a>
500
+
501
+ ``` cpp
502
+ void swap(jthread& x) noexcept;
503
+ ```
504
+
505
+ *Effects:* Exchanges the values of `*this` and `x`.
506
+
507
+ ``` cpp
508
+ [[nodiscard]] bool joinable() const noexcept;
509
+ ```
510
+
511
+ *Returns:* `get_id() != id()`.
512
+
513
+ ``` cpp
514
+ void join();
515
+ ```
516
+
517
+ *Effects:* Blocks until the thread represented by `*this` has completed.
518
+
519
+ *Synchronization:* The completion of the thread represented by `*this`
520
+ synchronizes with [[intro.multithread]] the corresponding successful
521
+ `join()` return.
522
+
523
+ [*Note 1*: Operations on `*this` are not synchronized. — *end note*]
524
+
525
+ *Ensures:* The thread represented by `*this` has completed.
526
+ `get_id() == id()`.
527
+
528
+ *Throws:* `system_error` when an exception is
529
+ required [[thread.req.exception]].
530
+
531
+ *Error conditions:*
532
+
533
+ - `resource_deadlock_would_occur` — if deadlock is detected or
534
+ `get_id() == this_thread::get_id()`.
535
+ - `no_such_process` — if the thread is not valid.
536
+ - `invalid_argument` — if the thread is not joinable.
537
+
538
+ ``` cpp
539
+ void detach();
540
+ ```
541
+
542
+ *Effects:* The thread represented by `*this` continues execution without
543
+ the calling thread blocking. When `detach()` returns, `*this` no longer
544
+ represents the possibly continuing thread of execution. When the thread
545
+ previously represented by `*this` ends execution, the implementation
546
+ releases any owned resources.
547
+
548
+ *Ensures:* `get_id() == id()`.
549
+
550
+ *Throws:* `system_error` when an exception is
551
+ required [[thread.req.exception]].
552
+
553
+ *Error conditions:*
554
+
555
+ - `no_such_process` — if the thread is not valid.
556
+ - `invalid_argument` — if the thread is not joinable.
557
+
558
+ ``` cpp
559
+ id get_id() const noexcept;
560
+ ```
561
+
562
+ *Returns:* A default constructed `id` object if `*this` does not
563
+ represent a thread, otherwise `this_thread::get_id()` for the thread of
564
+ execution represented by `*this`.
565
+
566
+ #### Stop token handling <a id="thread.jthread.stop">[[thread.jthread.stop]]</a>
567
+
568
+ ``` cpp
569
+ [[nodiscard]] stop_source get_stop_source() noexcept;
570
+ ```
571
+
572
+ *Effects:* Equivalent to: `return ssource;`
573
+
574
+ ``` cpp
575
+ [[nodiscard]] stop_token get_stop_token() const noexcept;
576
+ ```
577
+
578
+ *Effects:* Equivalent to: `return ssource.get_token();`
579
+
580
+ ``` cpp
581
+ bool request_stop() noexcept;
582
+ ```
583
+
584
+ *Effects:* Equivalent to: `return ssource.request_stop();`
585
+
586
+ #### Specialized algorithms <a id="thread.jthread.special">[[thread.jthread.special]]</a>
587
+
588
+ ``` cpp
589
+ friend void swap(jthread& x, jthread& y) noexcept;
590
+ ```
591
+
592
+ *Effects:* Equivalent to: `x.swap(y)`.
593
+
594
+ #### Static members <a id="thread.jthread.static">[[thread.jthread.static]]</a>
595
+
596
+ ``` cpp
597
+ [[nodiscard]] static unsigned int hardware_concurrency() noexcept;
598
+ ```
599
+
600
+ *Returns:* `thread::hardware_concurrency()`.
601
+
602
  ### Namespace `this_thread` <a id="thread.thread.this">[[thread.thread.this]]</a>
603
 
604
  ``` cpp
605
  namespace std::this_thread {
606
  thread::id get_id() noexcept;
 
616
  ``` cpp
617
  thread::id this_thread::get_id() noexcept;
618
  ```
619
 
620
  *Returns:* An object of type `thread::id` that uniquely identifies the
621
+ current thread of execution. No other thread of execution has this id
622
+ and this thread of execution always has this id. The object returned
623
+ does not compare equal to a default constructed `thread::id`.
 
624
 
625
  ``` cpp
626
  void this_thread::yield() noexcept;
627
  ```
628
 
 
634
  template<class Clock, class Duration>
635
  void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
636
  ```
637
 
638
  *Effects:* Blocks the calling thread for the absolute
639
+ timeout [[thread.req.timing]] specified by `abs_time`.
640
 
641
  *Synchronization:* None.
642
 
643
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
644
 
645
  ``` cpp
646
  template<class Rep, class Period>
647
  void sleep_for(const chrono::duration<Rep, Period>& rel_time);
648
  ```
649
 
650
  *Effects:* Blocks the calling thread for the relative
651
+ timeout [[thread.req.timing]] specified by `rel_time`.
652
 
653
  *Synchronization:* None.
654
 
655
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
656