tmp/tmp9r2gaxla/{from.md → to.md}
RENAMED
|
@@ -9,20 +9,20 @@ restricted to multi-threaded programs but can be useful in
|
|
| 9 |
single-threaded programs as well.
|
| 10 |
|
| 11 |
``` cpp
|
| 12 |
namespace std {
|
| 13 |
enum class future_errc {
|
| 14 |
-
broken_promise,
|
| 15 |
-
future_already_retrieved,
|
| 16 |
-
promise_already_satisfied,
|
| 17 |
-
no_state
|
| 18 |
};
|
| 19 |
|
| 20 |
enum class launch : unspecified{} {
|
| 21 |
async = unspecified{},
|
| 22 |
deferred = unspecified{},
|
| 23 |
-
implementation-defined
|
| 24 |
};
|
| 25 |
|
| 26 |
enum class future_status {
|
| 27 |
ready,
|
| 28 |
timeout,
|
|
@@ -57,33 +57,34 @@ namespace std {
|
|
| 57 |
|
| 58 |
template <class> class packaged_task; // undefined
|
| 59 |
template <class R, class... ArgTypes>
|
| 60 |
class packaged_task<R(ArgTypes...)>;
|
| 61 |
|
| 62 |
-
template <class R>
|
| 63 |
void swap(packaged_task<R(ArgTypes...)>&, packaged_task<R(ArgTypes...)>&) noexcept;
|
| 64 |
|
| 65 |
template <class R, class Alloc>
|
| 66 |
struct uses_allocator<packaged_task<R>, Alloc>;
|
| 67 |
|
| 68 |
template <class F, class... Args>
|
| 69 |
-
future<
|
| 70 |
async(F&& f, Args&&... args);
|
| 71 |
template <class F, class... Args>
|
| 72 |
-
future<
|
| 73 |
async(launch policy, F&& f, Args&&... args);
|
| 74 |
}
|
| 75 |
```
|
| 76 |
|
| 77 |
-
The `enum` type `launch` is
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
|
|
|
| 85 |
|
| 86 |
### Error handling <a id="futures.errors">[[futures.errors]]</a>
|
| 87 |
|
| 88 |
``` cpp
|
| 89 |
const error_category& future_category() noexcept;
|
|
@@ -144,11 +145,11 @@ a (possibly void) value or an exception. Futures, promises, and tasks
|
|
| 144 |
defined in this clause reference such shared state.
|
| 145 |
|
| 146 |
The result can be any kind of object including a function to compute
|
| 147 |
that result, as used by `async` when `policy` is `launch::deferred`.
|
| 148 |
|
| 149 |
-
An *asynchronous return object* is an object that reads results from
|
| 150 |
shared state. A *waiting function* of an asynchronous return object is
|
| 151 |
one that potentially blocks to wait for the shared state to be made
|
| 152 |
ready. If a waiting function can return before the state is made ready
|
| 153 |
because of a timeout ([[thread.req.lockable]]), then it is a *timed
|
| 154 |
waiting function*, otherwise it is a *non-timed waiting function*.
|
|
@@ -164,11 +165,15 @@ When an asynchronous return object or an asynchronous provider is said
|
|
| 164 |
to release its shared state, it means:
|
| 165 |
|
| 166 |
- if the return object or provider holds the last reference to its
|
| 167 |
shared state, the shared state is destroyed; and
|
| 168 |
- the return object or provider gives up its reference to its shared
|
| 169 |
-
state
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
|
| 171 |
When an asynchronous provider is said to make its shared state ready, it
|
| 172 |
means:
|
| 173 |
|
| 174 |
- first, the provider marks its shared state as ready; and
|
|
@@ -338,14 +343,14 @@ that state ready ([[futures.state]]).
|
|
| 338 |
|
| 339 |
*Throws:*
|
| 340 |
|
| 341 |
- `future_error` if its shared state already has a stored value or
|
| 342 |
exception, or
|
| 343 |
-
- for the first version, any exception thrown by the
|
| 344 |
-
`R`, or
|
| 345 |
-
- for the second version, any exception thrown by the
|
| 346 |
-
of `R`.
|
| 347 |
|
| 348 |
*Error conditions:*
|
| 349 |
|
| 350 |
- `promise_already_satisfied` if its shared state already has a stored
|
| 351 |
value or exception.
|
|
@@ -377,20 +382,27 @@ void promise<void>::set_value_at_thread_exit();
|
|
| 377 |
*Effects:* Stores the value `r` in the shared state without making that
|
| 378 |
state ready immediately. Schedules that state to be made ready when the
|
| 379 |
current thread exits, after all objects of thread storage duration
|
| 380 |
associated with the current thread have been destroyed.
|
| 381 |
|
| 382 |
-
*Throws:*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 383 |
|
| 384 |
*Error conditions:*
|
| 385 |
|
| 386 |
- `promise_already_satisfied` if its shared state already has a stored
|
| 387 |
value or exception.
|
| 388 |
- `no_state` if `*this` has no shared state.
|
| 389 |
|
| 390 |
``` cpp
|
| 391 |
-
void
|
| 392 |
```
|
| 393 |
|
| 394 |
*Effects:* Stores the exception pointer `p` in the shared state without
|
| 395 |
making that state ready immediately. Schedules that state to be made
|
| 396 |
ready when the current thread exits, after all objects of thread storage
|
|
@@ -468,11 +480,11 @@ out in its description, below.
|
|
| 468 |
``` cpp
|
| 469 |
future() noexcept;
|
| 470 |
```
|
| 471 |
|
| 472 |
*Effects:* constructs an *empty* `future` object that does not refer to
|
| 473 |
-
|
| 474 |
|
| 475 |
`valid() == false`.
|
| 476 |
|
| 477 |
``` cpp
|
| 478 |
future(future&& rhs) noexcept;
|
|
@@ -532,13 +544,12 @@ member function `get`.
|
|
| 532 |
*Effects:* `wait()`s until the shared state is ready, then retrieves the
|
| 533 |
value stored in the shared state.
|
| 534 |
|
| 535 |
*Returns:*
|
| 536 |
|
| 537 |
-
- `future::get()` returns the value stored in the object’s shared
|
| 538 |
-
|
| 539 |
-
moved, otherwise it is copied.
|
| 540 |
- `future<R&>::get()` returns the reference stored as value in the
|
| 541 |
object’s shared state.
|
| 542 |
- `future<void>::get()` returns nothing.
|
| 543 |
|
| 544 |
*Throws:* the stored exception, if an exception was stored in the shared
|
|
@@ -575,10 +586,12 @@ specified by `rel_time` has expired.
|
|
| 575 |
- `future_status::ready` if the shared state is ready.
|
| 576 |
- `future_status::timeout` if the function is returning because the
|
| 577 |
relative timeout ([[thread.req.timing]]) specified by `rel_time` has
|
| 578 |
expired.
|
| 579 |
|
|
|
|
|
|
|
| 580 |
``` cpp
|
| 581 |
template <class Clock, class Duration>
|
| 582 |
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
|
| 583 |
```
|
| 584 |
|
|
@@ -594,10 +607,12 @@ specified by `abs_time` has expired.
|
|
| 594 |
- `future_status::ready` if the shared state is ready.
|
| 595 |
- `future_status::timeout` if the function is returning because the
|
| 596 |
absolute timeout ([[thread.req.timing]]) specified by `abs_time` has
|
| 597 |
expired.
|
| 598 |
|
|
|
|
|
|
|
| 599 |
### Class template `shared_future` <a id="futures.shared_future">[[futures.shared_future]]</a>
|
| 600 |
|
| 601 |
The class template `shared_future` defines a type for asynchronous
|
| 602 |
return objects which may share their shared state with other
|
| 603 |
asynchronous return objects. A default-constructed `shared_future`
|
|
@@ -654,11 +669,11 @@ differ only in the return type and return value of the member function
|
|
| 654 |
``` cpp
|
| 655 |
shared_future() noexcept;
|
| 656 |
```
|
| 657 |
|
| 658 |
*Effects:* constructs an *empty* `shared_future` object that does not
|
| 659 |
-
refer to
|
| 660 |
|
| 661 |
`valid() == false`.
|
| 662 |
|
| 663 |
``` cpp
|
| 664 |
shared_future(const shared_future& rhs);
|
|
@@ -779,10 +794,12 @@ specified by `rel_time` has expired.
|
|
| 779 |
- `future_status::ready` if the shared state is ready.
|
| 780 |
- `future_status::timeout` if the function is returning because the
|
| 781 |
relative timeout ([[thread.req.timing]]) specified by `rel_time` has
|
| 782 |
expired.
|
| 783 |
|
|
|
|
|
|
|
| 784 |
``` cpp
|
| 785 |
template <class Clock, class Duration>
|
| 786 |
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
|
| 787 |
```
|
| 788 |
|
|
@@ -798,23 +815,23 @@ specified by `abs_time` has expired.
|
|
| 798 |
- `future_status::ready` if the shared state is ready.
|
| 799 |
- `future_status::timeout` if the function is returning because the
|
| 800 |
absolute timeout ([[thread.req.timing]]) specified by `abs_time` has
|
| 801 |
expired.
|
| 802 |
|
|
|
|
|
|
|
| 803 |
### Function template `async` <a id="futures.async">[[futures.async]]</a>
|
| 804 |
|
| 805 |
The function template `async` provides a mechanism to launch a function
|
| 806 |
potentially in a new thread and provides the result of the function in a
|
| 807 |
`future` object with which it shares a shared state.
|
| 808 |
|
| 809 |
``` cpp
|
| 810 |
template <class F, class... Args>
|
| 811 |
-
future<
|
| 812 |
-
async(F&& f, Args&&... args);
|
| 813 |
template <class F, class... Args>
|
| 814 |
-
future<
|
| 815 |
-
async(launch policy, F&& f, Args&&... args);
|
| 816 |
```
|
| 817 |
|
| 818 |
*Requires:* `F` and each `Ti` in `Args` shall satisfy the
|
| 819 |
`MoveConstructible` requirements.
|
| 820 |
*`INVOKE`*`(`*`DECAY_COPY`*`(std::forward<F>(f)), `*`DECAY_COPY`*`(std::forward<Args>(args))...)`
|
|
@@ -843,28 +860,37 @@ implementation may choose any of the corresponding policies):
|
|
| 843 |
asynchronous return objects that reference that state.
|
| 844 |
- if `policy & launch::deferred` is non-zero — Stores
|
| 845 |
*`DECAY_COPY`*`(std::forward<F>(f))` and
|
| 846 |
*`DECAY_COPY`*`(std::forward<Args>(args))...` in the shared state.
|
| 847 |
These copies of `f` and `args` constitute a *deferred function*.
|
| 848 |
-
Invocation of the deferred function evaluates
|
| 849 |
-
|
| 850 |
-
and `xyz` is the stored
|
| 851 |
-
*`DECAY_COPY`*`(std::forward<Args>(args))...`.
|
|
|
|
|
|
|
|
|
|
| 852 |
made ready until the function has completed. The first call to a
|
| 853 |
non-timed waiting function ([[futures.state]]) on an asynchronous
|
| 854 |
return object referring to this shared state shall invoke the deferred
|
| 855 |
function in the thread that called the waiting function. Once
|
| 856 |
-
evaluation of *`INVOKE`*`(g, xyz)` begins, the
|
| 857 |
-
considered deferred. If this policy is specified
|
| 858 |
-
policies, such as when using a `policy` value of
|
| 859 |
`launch::async | launch::deferred`, implementations should defer
|
| 860 |
invocation or the selection of the policy when no more concurrency can
|
| 861 |
be effectively exploited.
|
|
|
|
|
|
|
|
|
|
| 862 |
|
| 863 |
*Returns:* An object of type
|
| 864 |
-
`future<
|
| 865 |
-
state created by this call to `async`.
|
|
|
|
|
|
|
|
|
|
| 866 |
|
| 867 |
*Synchronization:* Regardless of the provided `policy` argument,
|
| 868 |
|
| 869 |
- the invocation of `async` synchronizes with ([[intro.multithread]])
|
| 870 |
the invocation of `f`. This statement applies even when the
|
|
@@ -875,29 +901,26 @@ state created by this call to `async`.
|
|
| 875 |
|
| 876 |
If the implementation chooses the `launch::async` policy,
|
| 877 |
|
| 878 |
- a call to a waiting function on an asynchronous return object that
|
| 879 |
shares the shared state created by this `async` call shall block until
|
| 880 |
-
the associated thread has completed, as if
|
| 881 |
-
|
| 882 |
- the associated thread completion synchronizes
|
| 883 |
with ([[intro.multithread]]) the return from the first function that
|
| 884 |
successfully detects the ready status of the shared state or with the
|
| 885 |
return from the last function that releases the shared state,
|
| 886 |
whichever happens first.
|
| 887 |
|
| 888 |
-
*Throws:* `system_error` if `policy
|
| 889 |
implementation is unable to start a new thread.
|
| 890 |
|
| 891 |
*Error conditions:*
|
| 892 |
|
| 893 |
-
- `resource_unavailable_try_again` — if `policy
|
| 894 |
the system is unable to start a new thread.
|
| 895 |
|
| 896 |
-
*Remarks:* The first signature shall not participate in overload
|
| 897 |
-
resolution if `decay<F>::type` is `std::launch`.
|
| 898 |
-
|
| 899 |
``` cpp
|
| 900 |
int work1(int value);
|
| 901 |
int work2(int value);
|
| 902 |
int work(int value) {
|
| 903 |
auto handle = std::async([=]{ return work2(value); });
|
|
@@ -937,12 +960,12 @@ namespace std {
|
|
| 937 |
template <class F, class Allocator>
|
| 938 |
explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
|
| 939 |
~packaged_task();
|
| 940 |
|
| 941 |
// no copy
|
| 942 |
-
packaged_task(packaged_task&) = delete;
|
| 943 |
-
packaged_task& operator=(packaged_task&) = delete;
|
| 944 |
|
| 945 |
// move support
|
| 946 |
packaged_task(packaged_task&& rhs) noexcept;
|
| 947 |
packaged_task& operator=(packaged_task&& rhs) noexcept;
|
| 948 |
void swap(packaged_task& other) noexcept;
|
|
@@ -984,10 +1007,14 @@ template <class F, class Allocator>
|
|
| 984 |
*Requires:* *`INVOKE`*`(f, t1, t2, ..., tN, R)`, where `t1, t2, ..., tN`
|
| 985 |
are values of the corresponding types in `ArgTypes...`, shall be a valid
|
| 986 |
expression. Invoking a copy of `f` shall behave the same as invoking
|
| 987 |
`f`.
|
| 988 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 989 |
*Effects:* constructs a new `packaged_task` object with a shared state
|
| 990 |
and initializes the object’s stored task with `std::forward<F>(f)`. The
|
| 991 |
constructors that take an `Allocator` argument use it to allocate memory
|
| 992 |
needed to store the internal data structures.
|
| 993 |
|
|
@@ -1071,20 +1098,10 @@ or the stored task has already been invoked.
|
|
| 1071 |
|
| 1072 |
- `promise_already_satisfied` if the stored task has already been
|
| 1073 |
invoked.
|
| 1074 |
- `no_state` if `*this` has no shared state.
|
| 1075 |
|
| 1076 |
-
*Synchronization:* a successful call to `operator()` synchronizes
|
| 1077 |
-
with ([[intro.multithread]]) a call to any member function of a
|
| 1078 |
-
`future` or `shared_future` object that shares the shared state of
|
| 1079 |
-
`*this`. The completion of the invocation of the stored task and the
|
| 1080 |
-
storage of the result (whether normal or exceptional) into the shared
|
| 1081 |
-
state synchronizes with ([[intro.multithread]]) the successful return
|
| 1082 |
-
from any member function that detects that the state is set to ready.
|
| 1083 |
-
`operator()` synchronizes and serializes with other functions through
|
| 1084 |
-
the shared state.
|
| 1085 |
-
|
| 1086 |
``` cpp
|
| 1087 |
void make_ready_at_thread_exit(ArgTypes... args);
|
| 1088 |
```
|
| 1089 |
|
| 1090 |
*Effects:* *`INVOKE`*`(f, t1, t2, ..., tN, R)`, where `f` is the stored
|
|
@@ -1144,10 +1161,11 @@ template <class R, class Alloc>
|
|
| 1144 |
[atomics]: atomics.md#atomics
|
| 1145 |
[basic.life]: basic.md#basic.life
|
| 1146 |
[basic.stc.thread]: basic.md#basic.stc.thread
|
| 1147 |
[bitmask.types]: library.md#bitmask.types
|
| 1148 |
[class]: class.md#class
|
|
|
|
| 1149 |
[func.require]: utilities.md#func.require
|
| 1150 |
[futures]: #futures
|
| 1151 |
[futures.async]: #futures.async
|
| 1152 |
[futures.errors]: #futures.errors
|
| 1153 |
[futures.future_error]: #futures.future_error
|
|
@@ -1172,10 +1190,15 @@ template <class R, class Alloc>
|
|
| 1172 |
[thread.decaycopy]: #thread.decaycopy
|
| 1173 |
[thread.general]: #thread.general
|
| 1174 |
[thread.lock]: #thread.lock
|
| 1175 |
[thread.lock.algorithm]: #thread.lock.algorithm
|
| 1176 |
[thread.lock.guard]: #thread.lock.guard
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1177 |
[thread.lock.unique]: #thread.lock.unique
|
| 1178 |
[thread.lock.unique.cons]: #thread.lock.unique.cons
|
| 1179 |
[thread.lock.unique.locking]: #thread.lock.unique.locking
|
| 1180 |
[thread.lock.unique.mod]: #thread.lock.unique.mod
|
| 1181 |
[thread.lock.unique.obs]: #thread.lock.unique.obs
|
|
@@ -1196,10 +1219,12 @@ template <class R, class Alloc>
|
|
| 1196 |
[thread.req.lockable.req]: #thread.req.lockable.req
|
| 1197 |
[thread.req.lockable.timed]: #thread.req.lockable.timed
|
| 1198 |
[thread.req.native]: #thread.req.native
|
| 1199 |
[thread.req.paramname]: #thread.req.paramname
|
| 1200 |
[thread.req.timing]: #thread.req.timing
|
|
|
|
|
|
|
| 1201 |
[thread.thread.algorithm]: #thread.thread.algorithm
|
| 1202 |
[thread.thread.assign]: #thread.thread.assign
|
| 1203 |
[thread.thread.class]: #thread.thread.class
|
| 1204 |
[thread.thread.constr]: #thread.thread.constr
|
| 1205 |
[thread.thread.destr]: #thread.thread.destr
|
|
|
|
| 9 |
single-threaded programs as well.
|
| 10 |
|
| 11 |
``` cpp
|
| 12 |
namespace std {
|
| 13 |
enum class future_errc {
|
| 14 |
+
broken_promise = implementation-defined,
|
| 15 |
+
future_already_retrieved = implementation-defined,
|
| 16 |
+
promise_already_satisfied = implementation-defined,
|
| 17 |
+
no_state = implementation-defined
|
| 18 |
};
|
| 19 |
|
| 20 |
enum class launch : unspecified{} {
|
| 21 |
async = unspecified{},
|
| 22 |
deferred = unspecified{},
|
| 23 |
+
implementation-defined
|
| 24 |
};
|
| 25 |
|
| 26 |
enum class future_status {
|
| 27 |
ready,
|
| 28 |
timeout,
|
|
|
|
| 57 |
|
| 58 |
template <class> class packaged_task; // undefined
|
| 59 |
template <class R, class... ArgTypes>
|
| 60 |
class packaged_task<R(ArgTypes...)>;
|
| 61 |
|
| 62 |
+
template <class R, class... ArgTypes>
|
| 63 |
void swap(packaged_task<R(ArgTypes...)>&, packaged_task<R(ArgTypes...)>&) noexcept;
|
| 64 |
|
| 65 |
template <class R, class Alloc>
|
| 66 |
struct uses_allocator<packaged_task<R>, Alloc>;
|
| 67 |
|
| 68 |
template <class F, class... Args>
|
| 69 |
+
future<result_of_t<decay_t<F>(decay_t<Args>...)>>
|
| 70 |
async(F&& f, Args&&... args);
|
| 71 |
template <class F, class... Args>
|
| 72 |
+
future<result_of_t<decay_t<F>(decay_t<Args>...)>>
|
| 73 |
async(launch policy, F&& f, Args&&... args);
|
| 74 |
}
|
| 75 |
```
|
| 76 |
|
| 77 |
+
The `enum` type `launch` is a bitmask type ([[bitmask.types]]) with
|
| 78 |
+
`launch::async` and `launch::deferred` denoting individual bits.
|
| 79 |
+
Implementations can provide bitmasks to specify restrictions on task
|
| 80 |
+
interaction by functions launched by `async()` applicable to a
|
| 81 |
+
corresponding subset of available launch policies. Implementations can
|
| 82 |
+
extend the behavior of the first overload of `async()` by adding their
|
| 83 |
+
extensions to the launch policy under the “as if” rule.
|
| 84 |
+
|
| 85 |
+
The enum values of `future_errc` are distinct and not zero.
|
| 86 |
|
| 87 |
### Error handling <a id="futures.errors">[[futures.errors]]</a>
|
| 88 |
|
| 89 |
``` cpp
|
| 90 |
const error_category& future_category() noexcept;
|
|
|
|
| 145 |
defined in this clause reference such shared state.
|
| 146 |
|
| 147 |
The result can be any kind of object including a function to compute
|
| 148 |
that result, as used by `async` when `policy` is `launch::deferred`.
|
| 149 |
|
| 150 |
+
An *asynchronous return object* is an object that reads results from a
|
| 151 |
shared state. A *waiting function* of an asynchronous return object is
|
| 152 |
one that potentially blocks to wait for the shared state to be made
|
| 153 |
ready. If a waiting function can return before the state is made ready
|
| 154 |
because of a timeout ([[thread.req.lockable]]), then it is a *timed
|
| 155 |
waiting function*, otherwise it is a *non-timed waiting function*.
|
|
|
|
| 165 |
to release its shared state, it means:
|
| 166 |
|
| 167 |
- if the return object or provider holds the last reference to its
|
| 168 |
shared state, the shared state is destroyed; and
|
| 169 |
- the return object or provider gives up its reference to its shared
|
| 170 |
+
state; and
|
| 171 |
+
- these actions will not block for the shared state to become ready,
|
| 172 |
+
except that it may block if all of the following are true: the shared
|
| 173 |
+
state was created by a call to `std::async`, the shared state is not
|
| 174 |
+
yet ready, and this was the last reference to the shared state.
|
| 175 |
|
| 176 |
When an asynchronous provider is said to make its shared state ready, it
|
| 177 |
means:
|
| 178 |
|
| 179 |
- first, the provider marks its shared state as ready; and
|
|
|
|
| 343 |
|
| 344 |
*Throws:*
|
| 345 |
|
| 346 |
- `future_error` if its shared state already has a stored value or
|
| 347 |
exception, or
|
| 348 |
+
- for the first version, any exception thrown by the constructor
|
| 349 |
+
selected to copy an object of `R`, or
|
| 350 |
+
- for the second version, any exception thrown by the constructor
|
| 351 |
+
selected to move an object of `R`.
|
| 352 |
|
| 353 |
*Error conditions:*
|
| 354 |
|
| 355 |
- `promise_already_satisfied` if its shared state already has a stored
|
| 356 |
value or exception.
|
|
|
|
| 382 |
*Effects:* Stores the value `r` in the shared state without making that
|
| 383 |
state ready immediately. Schedules that state to be made ready when the
|
| 384 |
current thread exits, after all objects of thread storage duration
|
| 385 |
associated with the current thread have been destroyed.
|
| 386 |
|
| 387 |
+
*Throws:*
|
| 388 |
+
|
| 389 |
+
- `future_error` if its shared state already has a stored value or
|
| 390 |
+
exception, or
|
| 391 |
+
- for the first version, any exception thrown by the constructor
|
| 392 |
+
selected to copy an object of `R`, or
|
| 393 |
+
- for the second version, any exception thrown by the constructor
|
| 394 |
+
selected to move an object of `R`.
|
| 395 |
|
| 396 |
*Error conditions:*
|
| 397 |
|
| 398 |
- `promise_already_satisfied` if its shared state already has a stored
|
| 399 |
value or exception.
|
| 400 |
- `no_state` if `*this` has no shared state.
|
| 401 |
|
| 402 |
``` cpp
|
| 403 |
+
void set_exception_at_thread_exit(exception_ptr p);
|
| 404 |
```
|
| 405 |
|
| 406 |
*Effects:* Stores the exception pointer `p` in the shared state without
|
| 407 |
making that state ready immediately. Schedules that state to be made
|
| 408 |
ready when the current thread exits, after all objects of thread storage
|
|
|
|
| 480 |
``` cpp
|
| 481 |
future() noexcept;
|
| 482 |
```
|
| 483 |
|
| 484 |
*Effects:* constructs an *empty* `future` object that does not refer to
|
| 485 |
+
a shared state.
|
| 486 |
|
| 487 |
`valid() == false`.
|
| 488 |
|
| 489 |
``` cpp
|
| 490 |
future(future&& rhs) noexcept;
|
|
|
|
| 544 |
*Effects:* `wait()`s until the shared state is ready, then retrieves the
|
| 545 |
value stored in the shared state.
|
| 546 |
|
| 547 |
*Returns:*
|
| 548 |
|
| 549 |
+
- `future::get()` returns the value `v` stored in the object’s shared
|
| 550 |
+
state as `std::move(v)`.
|
|
|
|
| 551 |
- `future<R&>::get()` returns the reference stored as value in the
|
| 552 |
object’s shared state.
|
| 553 |
- `future<void>::get()` returns nothing.
|
| 554 |
|
| 555 |
*Throws:* the stored exception, if an exception was stored in the shared
|
|
|
|
| 586 |
- `future_status::ready` if the shared state is ready.
|
| 587 |
- `future_status::timeout` if the function is returning because the
|
| 588 |
relative timeout ([[thread.req.timing]]) specified by `rel_time` has
|
| 589 |
expired.
|
| 590 |
|
| 591 |
+
*Throws:* timeout-related exceptions ([[thread.req.timing]]).
|
| 592 |
+
|
| 593 |
``` cpp
|
| 594 |
template <class Clock, class Duration>
|
| 595 |
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
|
| 596 |
```
|
| 597 |
|
|
|
|
| 607 |
- `future_status::ready` if the shared state is ready.
|
| 608 |
- `future_status::timeout` if the function is returning because the
|
| 609 |
absolute timeout ([[thread.req.timing]]) specified by `abs_time` has
|
| 610 |
expired.
|
| 611 |
|
| 612 |
+
*Throws:* timeout-related exceptions ([[thread.req.timing]]).
|
| 613 |
+
|
| 614 |
### Class template `shared_future` <a id="futures.shared_future">[[futures.shared_future]]</a>
|
| 615 |
|
| 616 |
The class template `shared_future` defines a type for asynchronous
|
| 617 |
return objects which may share their shared state with other
|
| 618 |
asynchronous return objects. A default-constructed `shared_future`
|
|
|
|
| 669 |
``` cpp
|
| 670 |
shared_future() noexcept;
|
| 671 |
```
|
| 672 |
|
| 673 |
*Effects:* constructs an *empty* `shared_future` object that does not
|
| 674 |
+
refer to a shared state.
|
| 675 |
|
| 676 |
`valid() == false`.
|
| 677 |
|
| 678 |
``` cpp
|
| 679 |
shared_future(const shared_future& rhs);
|
|
|
|
| 794 |
- `future_status::ready` if the shared state is ready.
|
| 795 |
- `future_status::timeout` if the function is returning because the
|
| 796 |
relative timeout ([[thread.req.timing]]) specified by `rel_time` has
|
| 797 |
expired.
|
| 798 |
|
| 799 |
+
*Throws:* timeout-related exceptions ([[thread.req.timing]]).
|
| 800 |
+
|
| 801 |
``` cpp
|
| 802 |
template <class Clock, class Duration>
|
| 803 |
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
|
| 804 |
```
|
| 805 |
|
|
|
|
| 815 |
- `future_status::ready` if the shared state is ready.
|
| 816 |
- `future_status::timeout` if the function is returning because the
|
| 817 |
absolute timeout ([[thread.req.timing]]) specified by `abs_time` has
|
| 818 |
expired.
|
| 819 |
|
| 820 |
+
*Throws:* timeout-related exceptions ([[thread.req.timing]]).
|
| 821 |
+
|
| 822 |
### Function template `async` <a id="futures.async">[[futures.async]]</a>
|
| 823 |
|
| 824 |
The function template `async` provides a mechanism to launch a function
|
| 825 |
potentially in a new thread and provides the result of the function in a
|
| 826 |
`future` object with which it shares a shared state.
|
| 827 |
|
| 828 |
``` cpp
|
| 829 |
template <class F, class... Args>
|
| 830 |
+
future<result_of_t<decay_t<F>(decay_t<Args>...)>> async(F&& f, Args&&... args);
|
|
|
|
| 831 |
template <class F, class... Args>
|
| 832 |
+
future<result_of_t<decay_t<F>(decay_t<Args>...)>> async(launch policy, F&& f, Args&&... args);
|
|
|
|
| 833 |
```
|
| 834 |
|
| 835 |
*Requires:* `F` and each `Ti` in `Args` shall satisfy the
|
| 836 |
`MoveConstructible` requirements.
|
| 837 |
*`INVOKE`*`(`*`DECAY_COPY`*`(std::forward<F>(f)), `*`DECAY_COPY`*`(std::forward<Args>(args))...)`
|
|
|
|
| 860 |
asynchronous return objects that reference that state.
|
| 861 |
- if `policy & launch::deferred` is non-zero — Stores
|
| 862 |
*`DECAY_COPY`*`(std::forward<F>(f))` and
|
| 863 |
*`DECAY_COPY`*`(std::forward<Args>(args))...` in the shared state.
|
| 864 |
These copies of `f` and `args` constitute a *deferred function*.
|
| 865 |
+
Invocation of the deferred function evaluates
|
| 866 |
+
*`INVOKE`*`(std::move(g), std::move(xyz))` where `g` is the stored
|
| 867 |
+
value of *`DECAY_COPY`*`(std::forward<F>(f))` and `xyz` is the stored
|
| 868 |
+
copy of *`DECAY_COPY`*`(std::forward<Args>(args))...`. Any return
|
| 869 |
+
value is stored as the result in the shared state. Any exception
|
| 870 |
+
propagated from the execution of the deferred function is stored as
|
| 871 |
+
the exceptional result in the shared state. The shared state is not
|
| 872 |
made ready until the function has completed. The first call to a
|
| 873 |
non-timed waiting function ([[futures.state]]) on an asynchronous
|
| 874 |
return object referring to this shared state shall invoke the deferred
|
| 875 |
function in the thread that called the waiting function. Once
|
| 876 |
+
evaluation of *`INVOKE`*`(std::move(g), std::move(xyz))` begins, the
|
| 877 |
+
function is no longer considered deferred. If this policy is specified
|
| 878 |
+
together with other policies, such as when using a `policy` value of
|
| 879 |
`launch::async | launch::deferred`, implementations should defer
|
| 880 |
invocation or the selection of the policy when no more concurrency can
|
| 881 |
be effectively exploited.
|
| 882 |
+
- If no value is set in the launch policy, or a value is set that is
|
| 883 |
+
neither specified in this International Standard or by the
|
| 884 |
+
implementation, the behaviour is undefined.
|
| 885 |
|
| 886 |
*Returns:* An object of type
|
| 887 |
+
`future<result_of_t<decay_t<F>(decay_t<Args>...)>``>` that refers to the
|
| 888 |
+
shared state created by this call to `async`. If a future obtained from
|
| 889 |
+
std::async is moved outside the local scope, other code that uses the
|
| 890 |
+
future must be aware that the future’s destructor may block for the
|
| 891 |
+
shared state to become ready.
|
| 892 |
|
| 893 |
*Synchronization:* Regardless of the provided `policy` argument,
|
| 894 |
|
| 895 |
- the invocation of `async` synchronizes with ([[intro.multithread]])
|
| 896 |
the invocation of `f`. This statement applies even when the
|
|
|
|
| 901 |
|
| 902 |
If the implementation chooses the `launch::async` policy,
|
| 903 |
|
| 904 |
- a call to a waiting function on an asynchronous return object that
|
| 905 |
shares the shared state created by this `async` call shall block until
|
| 906 |
+
the associated thread has completed, as if joined, or else time
|
| 907 |
+
out ([[thread.thread.member]]);
|
| 908 |
- the associated thread completion synchronizes
|
| 909 |
with ([[intro.multithread]]) the return from the first function that
|
| 910 |
successfully detects the ready status of the shared state or with the
|
| 911 |
return from the last function that releases the shared state,
|
| 912 |
whichever happens first.
|
| 913 |
|
| 914 |
+
*Throws:* `system_error` if `policy == launch::async` and the
|
| 915 |
implementation is unable to start a new thread.
|
| 916 |
|
| 917 |
*Error conditions:*
|
| 918 |
|
| 919 |
+
- `resource_unavailable_try_again` — if `policy == launch::async` and
|
| 920 |
the system is unable to start a new thread.
|
| 921 |
|
|
|
|
|
|
|
|
|
|
| 922 |
``` cpp
|
| 923 |
int work1(int value);
|
| 924 |
int work2(int value);
|
| 925 |
int work(int value) {
|
| 926 |
auto handle = std::async([=]{ return work2(value); });
|
|
|
|
| 960 |
template <class F, class Allocator>
|
| 961 |
explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
|
| 962 |
~packaged_task();
|
| 963 |
|
| 964 |
// no copy
|
| 965 |
+
packaged_task(const packaged_task&) = delete;
|
| 966 |
+
packaged_task& operator=(const packaged_task&) = delete;
|
| 967 |
|
| 968 |
// move support
|
| 969 |
packaged_task(packaged_task&& rhs) noexcept;
|
| 970 |
packaged_task& operator=(packaged_task&& rhs) noexcept;
|
| 971 |
void swap(packaged_task& other) noexcept;
|
|
|
|
| 1007 |
*Requires:* *`INVOKE`*`(f, t1, t2, ..., tN, R)`, where `t1, t2, ..., tN`
|
| 1008 |
are values of the corresponding types in `ArgTypes...`, shall be a valid
|
| 1009 |
expression. Invoking a copy of `f` shall behave the same as invoking
|
| 1010 |
`f`.
|
| 1011 |
|
| 1012 |
+
*Remarks:* These constructors shall not participate in overload
|
| 1013 |
+
resolution if `decay_t<F>` is the same type as
|
| 1014 |
+
`std::packaged_task<R(ArgTypes...)>`.
|
| 1015 |
+
|
| 1016 |
*Effects:* constructs a new `packaged_task` object with a shared state
|
| 1017 |
and initializes the object’s stored task with `std::forward<F>(f)`. The
|
| 1018 |
constructors that take an `Allocator` argument use it to allocate memory
|
| 1019 |
needed to store the internal data structures.
|
| 1020 |
|
|
|
|
| 1098 |
|
| 1099 |
- `promise_already_satisfied` if the stored task has already been
|
| 1100 |
invoked.
|
| 1101 |
- `no_state` if `*this` has no shared state.
|
| 1102 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1103 |
``` cpp
|
| 1104 |
void make_ready_at_thread_exit(ArgTypes... args);
|
| 1105 |
```
|
| 1106 |
|
| 1107 |
*Effects:* *`INVOKE`*`(f, t1, t2, ..., tN, R)`, where `f` is the stored
|
|
|
|
| 1161 |
[atomics]: atomics.md#atomics
|
| 1162 |
[basic.life]: basic.md#basic.life
|
| 1163 |
[basic.stc.thread]: basic.md#basic.stc.thread
|
| 1164 |
[bitmask.types]: library.md#bitmask.types
|
| 1165 |
[class]: class.md#class
|
| 1166 |
+
[except.terminate]: except.md#except.terminate
|
| 1167 |
[func.require]: utilities.md#func.require
|
| 1168 |
[futures]: #futures
|
| 1169 |
[futures.async]: #futures.async
|
| 1170 |
[futures.errors]: #futures.errors
|
| 1171 |
[futures.future_error]: #futures.future_error
|
|
|
|
| 1190 |
[thread.decaycopy]: #thread.decaycopy
|
| 1191 |
[thread.general]: #thread.general
|
| 1192 |
[thread.lock]: #thread.lock
|
| 1193 |
[thread.lock.algorithm]: #thread.lock.algorithm
|
| 1194 |
[thread.lock.guard]: #thread.lock.guard
|
| 1195 |
+
[thread.lock.shared]: #thread.lock.shared
|
| 1196 |
+
[thread.lock.shared.cons]: #thread.lock.shared.cons
|
| 1197 |
+
[thread.lock.shared.locking]: #thread.lock.shared.locking
|
| 1198 |
+
[thread.lock.shared.mod]: #thread.lock.shared.mod
|
| 1199 |
+
[thread.lock.shared.obs]: #thread.lock.shared.obs
|
| 1200 |
[thread.lock.unique]: #thread.lock.unique
|
| 1201 |
[thread.lock.unique.cons]: #thread.lock.unique.cons
|
| 1202 |
[thread.lock.unique.locking]: #thread.lock.unique.locking
|
| 1203 |
[thread.lock.unique.mod]: #thread.lock.unique.mod
|
| 1204 |
[thread.lock.unique.obs]: #thread.lock.unique.obs
|
|
|
|
| 1219 |
[thread.req.lockable.req]: #thread.req.lockable.req
|
| 1220 |
[thread.req.lockable.timed]: #thread.req.lockable.timed
|
| 1221 |
[thread.req.native]: #thread.req.native
|
| 1222 |
[thread.req.paramname]: #thread.req.paramname
|
| 1223 |
[thread.req.timing]: #thread.req.timing
|
| 1224 |
+
[thread.sharedtimedmutex.class]: #thread.sharedtimedmutex.class
|
| 1225 |
+
[thread.sharedtimedmutex.requirements]: #thread.sharedtimedmutex.requirements
|
| 1226 |
[thread.thread.algorithm]: #thread.thread.algorithm
|
| 1227 |
[thread.thread.assign]: #thread.thread.assign
|
| 1228 |
[thread.thread.class]: #thread.thread.class
|
| 1229 |
[thread.thread.constr]: #thread.thread.constr
|
| 1230 |
[thread.thread.destr]: #thread.thread.destr
|