tmp/tmp5lkdvra0/{from.md → to.md}
RENAMED
|
@@ -4,81 +4,91 @@ The function template `async` provides a mechanism to launch a function
|
|
| 4 |
potentially in a new thread and provides the result of the function in a
|
| 5 |
`future` object with which it shares a shared state.
|
| 6 |
|
| 7 |
``` cpp
|
| 8 |
template <class F, class... Args>
|
| 9 |
-
future<
|
|
|
|
| 10 |
template <class F, class... Args>
|
| 11 |
-
future<
|
|
|
|
| 12 |
```
|
| 13 |
|
| 14 |
*Requires:* `F` and each `Ti` in `Args` shall satisfy the
|
| 15 |
-
`MoveConstructible` requirements
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
|
| 20 |
*Effects:* The first function behaves the same as a call to the second
|
| 21 |
function with a `policy` argument of `launch::async | launch::deferred`
|
| 22 |
and the same arguments for `F` and `Args`. The second function creates a
|
| 23 |
shared state that is associated with the returned `future` object. The
|
| 24 |
further behavior of the second function depends on the `policy` argument
|
| 25 |
as follows (if more than one of these conditions applies, the
|
| 26 |
implementation may choose any of the corresponding policies):
|
| 27 |
|
| 28 |
-
-
|
| 29 |
-
*
|
| 30 |
-
*
|
| 31 |
[[thread.thread.constr]]) as if in a new thread of execution
|
| 32 |
-
represented by a `thread` object with the calls to *
|
| 33 |
being evaluated in the thread that called `async`. Any return value is
|
| 34 |
stored as the result in the shared state. Any exception propagated
|
| 35 |
-
from the execution of
|
| 36 |
-
*
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
-
|
| 41 |
-
*
|
| 42 |
-
*
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
together with other policies, such as when using a `policy` value of
|
| 58 |
`launch::async | launch::deferred`, implementations should defer
|
| 59 |
invocation or the selection of the policy when no more concurrency can
|
| 60 |
-
be effectively exploited.
|
| 61 |
- If no value is set in the launch policy, or a value is set that is
|
| 62 |
-
neither specified in this International Standard
|
| 63 |
-
implementation, the
|
| 64 |
|
| 65 |
*Returns:* An object of type
|
| 66 |
-
`future<
|
| 67 |
-
shared state created by this call to `async`.
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
|
|
|
|
|
|
| 71 |
|
| 72 |
*Synchronization:* Regardless of the provided `policy` argument,
|
| 73 |
|
| 74 |
- the invocation of `async` synchronizes with ([[intro.multithread]])
|
| 75 |
-
the invocation of `f`. This statement applies even when
|
| 76 |
-
corresponding `future` object is moved to another
|
|
|
|
| 77 |
- the completion of the function `f` is sequenced
|
| 78 |
-
before ([[intro.multithread]]) the shared state is made ready.
|
| 79 |
-
might not be called at all, so its completion might
|
|
|
|
| 80 |
|
| 81 |
If the implementation chooses the `launch::async` policy,
|
| 82 |
|
| 83 |
- a call to a waiting function on an asynchronous return object that
|
| 84 |
shares the shared state created by this `async` call shall block until
|
|
@@ -89,28 +99,19 @@ If the implementation chooses the `launch::async` policy,
|
|
| 89 |
successfully detects the ready status of the shared state or with the
|
| 90 |
return from the last function that releases the shared state,
|
| 91 |
whichever happens first.
|
| 92 |
|
| 93 |
*Throws:* `system_error` if `policy == launch::async` and the
|
| 94 |
-
implementation is unable to start a new thread
|
|
|
|
| 95 |
|
| 96 |
*Error conditions:*
|
| 97 |
|
| 98 |
- `resource_unavailable_try_again` — if `policy == launch::async` and
|
| 99 |
the system is unable to start a new thread.
|
| 100 |
|
| 101 |
-
``
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
int tmp = work1(value);
|
| 107 |
-
return tmp + handle.get(); // #1
|
| 108 |
-
}
|
| 109 |
-
```
|
| 110 |
-
|
| 111 |
-
Line \#1 might not result in concurrency because the `async` call uses
|
| 112 |
-
the default policy, which may use `launch::deferred`, in which case the
|
| 113 |
-
lambda might not be invoked until the `get()` call; in that case,
|
| 114 |
-
`work1` and `work2` are called on the same thread and there is no
|
| 115 |
-
concurrency.
|
| 116 |
|
|
|
|
| 4 |
potentially in a new thread and provides the result of the function in a
|
| 5 |
`future` object with which it shares a shared state.
|
| 6 |
|
| 7 |
``` cpp
|
| 8 |
template <class F, class... Args>
|
| 9 |
+
future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
|
| 10 |
+
async(F&& f, Args&&... args);
|
| 11 |
template <class F, class... Args>
|
| 12 |
+
future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
|
| 13 |
+
async(launch policy, F&& f, Args&&... args);
|
| 14 |
```
|
| 15 |
|
| 16 |
*Requires:* `F` and each `Ti` in `Args` shall satisfy the
|
| 17 |
+
`MoveConstructible` requirements, and
|
| 18 |
+
|
| 19 |
+
``` cpp
|
| 20 |
+
INVOKE(DECAY_COPY(std::forward<F>(f)),
|
| 21 |
+
DECAY_COPY(std::forward<Args>(args))...) // see [func.require] [thread.thread.constr]
|
| 22 |
+
```
|
| 23 |
+
|
| 24 |
+
shall be a valid expression.
|
| 25 |
|
| 26 |
*Effects:* The first function behaves the same as a call to the second
|
| 27 |
function with a `policy` argument of `launch::async | launch::deferred`
|
| 28 |
and the same arguments for `F` and `Args`. The second function creates a
|
| 29 |
shared state that is associated with the returned `future` object. The
|
| 30 |
further behavior of the second function depends on the `policy` argument
|
| 31 |
as follows (if more than one of these conditions applies, the
|
| 32 |
implementation may choose any of the corresponding policies):
|
| 33 |
|
| 34 |
+
- If `launch::async` is set in `policy`, calls
|
| 35 |
+
*INVOKE*(*DECAY_COPY*(std::forward\<F\>(f)),
|
| 36 |
+
*DECAY_COPY*(std::forward\<Args\>(args))...) ([[func.require]],
|
| 37 |
[[thread.thread.constr]]) as if in a new thread of execution
|
| 38 |
+
represented by a `thread` object with the calls to *DECAY_COPY*()
|
| 39 |
being evaluated in the thread that called `async`. Any return value is
|
| 40 |
stored as the result in the shared state. Any exception propagated
|
| 41 |
+
from the execution of *INVOKE*(*DECAY_COPY*(std::forward\<F\>(f)),
|
| 42 |
+
*DECAY_COPY*(std::forward\<Args\>(args))...) is stored as the
|
| 43 |
+
exceptional result in the shared state. The `thread` object is stored
|
| 44 |
+
in the shared state and affects the behavior of any asynchronous
|
| 45 |
+
return objects that reference that state.
|
| 46 |
+
- If `launch::deferred` is set in `policy`, stores
|
| 47 |
+
*DECAY_COPY*(std::forward\<F\>(f)) and
|
| 48 |
+
*DECAY_COPY*(std::forward\<Args\>(args))... in the shared state. These
|
| 49 |
+
copies of `f` and `args` constitute a *deferred function*. Invocation
|
| 50 |
+
of the deferred function evaluates *INVOKE*(std::move(g),
|
| 51 |
+
std::move(xyz)) where `g` is the stored value of
|
| 52 |
+
*DECAY_COPY*(std::forward\<F\>(f)) and `xyz` is the stored copy of
|
| 53 |
+
*DECAY_COPY*(std::forward\<Args\>(args)).... Any return value is
|
| 54 |
+
stored as the result in the shared state. Any exception propagated
|
| 55 |
+
from the execution of the deferred function is stored as the
|
| 56 |
+
exceptional result in the shared state. The shared state is not made
|
| 57 |
+
ready until the function has completed. The first call to a non-timed
|
| 58 |
+
waiting function ([[futures.state]]) on an asynchronous return object
|
| 59 |
+
referring to this shared state shall invoke the deferred function in
|
| 60 |
+
the thread that called the waiting function. Once evaluation of
|
| 61 |
+
*INVOKE*(std::move(g), std::move(xyz)) begins, the function is no
|
| 62 |
+
longer considered deferred. \[*Note 1*: If this policy is specified
|
| 63 |
together with other policies, such as when using a `policy` value of
|
| 64 |
`launch::async | launch::deferred`, implementations should defer
|
| 65 |
invocation or the selection of the policy when no more concurrency can
|
| 66 |
+
be effectively exploited. — *end note*]
|
| 67 |
- If no value is set in the launch policy, or a value is set that is
|
| 68 |
+
neither specified in this International Standard nor by the
|
| 69 |
+
implementation, the behavior is undefined.
|
| 70 |
|
| 71 |
*Returns:* An object of type
|
| 72 |
+
`future<invoke_result_t<decay_t<F>, decay_t<Args>...>``>` that refers to
|
| 73 |
+
the shared state created by this call to `async`.
|
| 74 |
+
|
| 75 |
+
[*Note 1*: If a future obtained from `async` is moved outside the local
|
| 76 |
+
scope, other code that uses the future must be aware that the future’s
|
| 77 |
+
destructor may block for the shared state to become
|
| 78 |
+
ready. — *end note*]
|
| 79 |
|
| 80 |
*Synchronization:* Regardless of the provided `policy` argument,
|
| 81 |
|
| 82 |
- the invocation of `async` synchronizes with ([[intro.multithread]])
|
| 83 |
+
the invocation of `f`. \[*Note 2*: This statement applies even when
|
| 84 |
+
the corresponding `future` object is moved to another
|
| 85 |
+
thread. — *end note*] ; and
|
| 86 |
- the completion of the function `f` is sequenced
|
| 87 |
+
before ([[intro.multithread]]) the shared state is made ready.
|
| 88 |
+
\[*Note 3*: `f` might not be called at all, so its completion might
|
| 89 |
+
never happen. — *end note*]
|
| 90 |
|
| 91 |
If the implementation chooses the `launch::async` policy,
|
| 92 |
|
| 93 |
- a call to a waiting function on an asynchronous return object that
|
| 94 |
shares the shared state created by this `async` call shall block until
|
|
|
|
| 99 |
successfully detects the ready status of the shared state or with the
|
| 100 |
return from the last function that releases the shared state,
|
| 101 |
whichever happens first.
|
| 102 |
|
| 103 |
*Throws:* `system_error` if `policy == launch::async` and the
|
| 104 |
+
implementation is unable to start a new thread, or `std::bad_alloc` if
|
| 105 |
+
memory for the internal data structures could not be allocated.
|
| 106 |
|
| 107 |
*Error conditions:*
|
| 108 |
|
| 109 |
- `resource_unavailable_try_again` — if `policy == launch::async` and
|
| 110 |
the system is unable to start a new thread.
|
| 111 |
|
| 112 |
+
[*Note 4*: Line \#1 might not result in concurrency because the `async`
|
| 113 |
+
call uses the default policy, which may use `launch::deferred`, in which
|
| 114 |
+
case the lambda might not be invoked until the `get()` call; in that
|
| 115 |
+
case, `work1` and `work2` are called on the same thread and there is no
|
| 116 |
+
concurrency. — *end note*]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
|