From Jason Turner

[thread.jthread.class]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpgsl86izb/{from.md → to.md} +256 -0
tmp/tmpgsl86izb/{from.md → to.md} RENAMED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Class `jthread` <a id="thread.jthread.class">[[thread.jthread.class]]</a>
2
+
3
+ The class `jthread` provides a mechanism to create a new thread of
4
+ execution. The functionality is the same as for class `thread`
5
+ [[thread.thread.class]] with the additional abilities to provide a
6
+ `stop_token` [[thread.stoptoken]] to the new thread of execution, make
7
+ stop requests, and automatically join.
8
+
9
+ ``` cpp
10
+ namespace std {
11
+ class jthread {
12
+ public:
13
+ // types
14
+ using id = thread::id;
15
+ using native_handle_type = thread::native_handle_type;
16
+
17
+ // [thread.jthread.cons], constructors, move, and assignment
18
+ jthread() noexcept;
19
+ template<class F, class... Args> explicit jthread(F&& f, Args&&... args);
20
+ ~jthread();
21
+ jthread(const jthread&) = delete;
22
+ jthread(jthread&&) noexcept;
23
+ jthread& operator=(const jthread&) = delete;
24
+ jthread& operator=(jthread&&) noexcept;
25
+
26
+ // [thread.jthread.mem], members
27
+ void swap(jthread&) noexcept;
28
+ [[nodiscard]] bool joinable() const noexcept;
29
+ void join();
30
+ void detach();
31
+ [[nodiscard]] id get_id() const noexcept;
32
+ [[nodiscard]] native_handle_type native_handle(); // see~[thread.req.native]
33
+
34
+ // [thread.jthread.stop], stop token handling
35
+ [[nodiscard]] stop_source get_stop_source() noexcept;
36
+ [[nodiscard]] stop_token get_stop_token() const noexcept;
37
+ bool request_stop() noexcept;
38
+
39
+ // [thread.jthread.special], specialized algorithms
40
+ friend void swap(jthread& lhs, jthread& rhs) noexcept;
41
+
42
+ // [thread.jthread.static], static members
43
+ [[nodiscard]] static unsigned int hardware_concurrency() noexcept;
44
+
45
+ private:
46
+ stop_source ssource; // exposition only
47
+ };
48
+ }
49
+ ```
50
+
51
+ #### Constructors, move, and assignment <a id="thread.jthread.cons">[[thread.jthread.cons]]</a>
52
+
53
+ ``` cpp
54
+ jthread() noexcept;
55
+ ```
56
+
57
+ *Effects:* Constructs a `jthread` object that does not represent a
58
+ thread of execution.
59
+
60
+ *Ensures:* `get_id() == id()` is `true` and `ssource.stop_possible()` is
61
+ `false`.
62
+
63
+ ``` cpp
64
+ template<class F, class... Args> explicit jthread(F&& f, Args&&... args);
65
+ ```
66
+
67
+ *Constraints:* `remove_cvref_t<F>` is not the same type as `jthread`.
68
+
69
+ *Mandates:* The following are all `true`:
70
+
71
+ - `is_constructible_v<decay_t<F>, F>`,
72
+ - `(is_constructible_v<decay_t<Args>, Args> && ...)`,
73
+ - `is_move_constructible_v<decay_t<F>>`,
74
+ - `(is_move_constructible_v<decay_t<Args>> && ...)`, and
75
+ - `is_invocable_v<decay_t<F>, decay_t<Args>...> ||`
76
+ `is_invocable_v<decay_t<F>, stop_token, decay_t<Args>...>`.
77
+
78
+ *Preconditions:* `decay_t<F>` and each type in `decay_t<Args>` meet the
79
+ *Cpp17MoveConstructible* requirements.
80
+
81
+ *Effects:* Initializes `ssource`. The new thread of execution executes
82
+
83
+ ``` cpp
84
+ invoke(decay-copy(std::forward<F>(f)), get_stop_token(),
85
+ decay-copy(std::forward<Args>(args))...)
86
+ ```
87
+
88
+ if that expression is well-formed, otherwise
89
+
90
+ ``` cpp
91
+ invoke(decay-copy(std::forward<F>(f)), decay-copy(std::forward<Args>(args))...)
92
+ ```
93
+
94
+ with the calls to *`decay-copy`* being evaluated in the constructing
95
+ thread. Any return value from this invocation is ignored.
96
+
97
+ [*Note 1*: This implies that any exceptions not thrown from the
98
+ invocation of the copy of `f` will be thrown in the constructing thread,
99
+ not the new thread. — *end note*]
100
+
101
+ If the `invoke` expression exits via an exception, `terminate` is
102
+ called.
103
+
104
+ *Synchronization:* The completion of the invocation of the constructor
105
+ synchronizes with the beginning of the invocation of the copy of `f`.
106
+
107
+ *Ensures:* `get_id() != id()` is `true` and `ssource.stop_possible()` is
108
+ `true` and `*this` represents the newly started thread.
109
+
110
+ [*Note 2*: The calling thread can make a stop request only once,
111
+ because it cannot replace this stop token. — *end note*]
112
+
113
+ *Throws:* `system_error` if unable to start the new thread.
114
+
115
+ *Error conditions:*
116
+
117
+ - `resource_unavailable_try_again` — the system lacked the necessary
118
+ resources to create another thread, or the system-imposed limit on the
119
+ number of threads in a process would be exceeded.
120
+
121
+ ``` cpp
122
+ jthread(jthread&& x) noexcept;
123
+ ```
124
+
125
+ *Ensures:* `x.get_id() == id()` and `get_id()` returns the value of
126
+ `x.get_id()` prior to the start of construction. `ssource` has the value
127
+ of `x.ssource` prior to the start of construction and
128
+ `x.ssource.stop_possible()` is `false`.
129
+
130
+ ``` cpp
131
+ ~jthread();
132
+ ```
133
+
134
+ *Effects:* If `joinable()` is `true`, calls `request_stop()` and then
135
+ `join()`.
136
+
137
+ [*Note 3*: Operations on `*this` are not synchronized. — *end note*]
138
+
139
+ ``` cpp
140
+ jthread& operator=(jthread&& x) noexcept;
141
+ ```
142
+
143
+ *Effects:* If `joinable()` is `true`, calls `request_stop()` and then
144
+ `join()`. Assigns the state of `x` to `*this` and sets `x` to a default
145
+ constructed state.
146
+
147
+ *Ensures:* `x.get_id() == id()` and `get_id()` returns the value of
148
+ `x.get_id()` prior to the assignment. `ssource` has the value of
149
+ `x.ssource` prior to the assignment and `x.ssource.stop_possible()` is
150
+ `false`.
151
+
152
+ *Returns:* `*this`.
153
+
154
+ #### Members <a id="thread.jthread.mem">[[thread.jthread.mem]]</a>
155
+
156
+ ``` cpp
157
+ void swap(jthread& x) noexcept;
158
+ ```
159
+
160
+ *Effects:* Exchanges the values of `*this` and `x`.
161
+
162
+ ``` cpp
163
+ [[nodiscard]] bool joinable() const noexcept;
164
+ ```
165
+
166
+ *Returns:* `get_id() != id()`.
167
+
168
+ ``` cpp
169
+ void join();
170
+ ```
171
+
172
+ *Effects:* Blocks until the thread represented by `*this` has completed.
173
+
174
+ *Synchronization:* The completion of the thread represented by `*this`
175
+ synchronizes with [[intro.multithread]] the corresponding successful
176
+ `join()` return.
177
+
178
+ [*Note 1*: Operations on `*this` are not synchronized. — *end note*]
179
+
180
+ *Ensures:* The thread represented by `*this` has completed.
181
+ `get_id() == id()`.
182
+
183
+ *Throws:* `system_error` when an exception is
184
+ required [[thread.req.exception]].
185
+
186
+ *Error conditions:*
187
+
188
+ - `resource_deadlock_would_occur` — if deadlock is detected or
189
+ `get_id() == this_thread::get_id()`.
190
+ - `no_such_process` — if the thread is not valid.
191
+ - `invalid_argument` — if the thread is not joinable.
192
+
193
+ ``` cpp
194
+ void detach();
195
+ ```
196
+
197
+ *Effects:* The thread represented by `*this` continues execution without
198
+ the calling thread blocking. When `detach()` returns, `*this` no longer
199
+ represents the possibly continuing thread of execution. When the thread
200
+ previously represented by `*this` ends execution, the implementation
201
+ releases any owned resources.
202
+
203
+ *Ensures:* `get_id() == id()`.
204
+
205
+ *Throws:* `system_error` when an exception is
206
+ required [[thread.req.exception]].
207
+
208
+ *Error conditions:*
209
+
210
+ - `no_such_process` — if the thread is not valid.
211
+ - `invalid_argument` — if the thread is not joinable.
212
+
213
+ ``` cpp
214
+ id get_id() const noexcept;
215
+ ```
216
+
217
+ *Returns:* A default constructed `id` object if `*this` does not
218
+ represent a thread, otherwise `this_thread::get_id()` for the thread of
219
+ execution represented by `*this`.
220
+
221
+ #### Stop token handling <a id="thread.jthread.stop">[[thread.jthread.stop]]</a>
222
+
223
+ ``` cpp
224
+ [[nodiscard]] stop_source get_stop_source() noexcept;
225
+ ```
226
+
227
+ *Effects:* Equivalent to: `return ssource;`
228
+
229
+ ``` cpp
230
+ [[nodiscard]] stop_token get_stop_token() const noexcept;
231
+ ```
232
+
233
+ *Effects:* Equivalent to: `return ssource.get_token();`
234
+
235
+ ``` cpp
236
+ bool request_stop() noexcept;
237
+ ```
238
+
239
+ *Effects:* Equivalent to: `return ssource.request_stop();`
240
+
241
+ #### Specialized algorithms <a id="thread.jthread.special">[[thread.jthread.special]]</a>
242
+
243
+ ``` cpp
244
+ friend void swap(jthread& x, jthread& y) noexcept;
245
+ ```
246
+
247
+ *Effects:* Equivalent to: `x.swap(y)`.
248
+
249
+ #### Static members <a id="thread.jthread.static">[[thread.jthread.static]]</a>
250
+
251
+ ``` cpp
252
+ [[nodiscard]] static unsigned int hardware_concurrency() noexcept;
253
+ ```
254
+
255
+ *Returns:* `thread::hardware_concurrency()`.
256
+