Files
2025-10-25 03:02:53 +03:00

178 lines
6.8 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[futures.state]
# 32 Concurrency support library [[thread]](./#thread)
## 32.10 Futures [[futures]](futures#state)
### 32.10.5 Shared state [futures.state]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11311)
Many of the classes introduced in subclause [[futures]](futures "32.10Futures") use some state to communicate results[.](#1.sentence-1)
This
[*shared state*](#def:future,shared_state "32.10.5Shared state[futures.state]") consists of some state information and some (possibly not
yet evaluated) [*result*](#def:result), which can be a (possibly void) value or an exception[.](#1.sentence-2)
[*Note [1](#note-1)*:
Futures, promises, and tasks defined in this Clause reference such shared state[.](#1.sentence-3)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11320)
[*Note [2](#note-2)*:
The result can be any kind of object including a function to compute that result,
as used by async when policy is launch::deferred[.](#2.sentence-1)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11326)
An [*asynchronous return object*](#def:asynchronous_return_object "32.10.5Shared state[futures.state]") is an object that reads results from a
shared state[.](#3.sentence-1)
A [*waiting function*](#def:function,waiting "32.10.5Shared state[futures.state]") of an asynchronous return object is one
that potentially blocks to wait for the shared state to be made
ready[.](#3.sentence-2)
If a waiting function can return before the state is made ready because of a
timeout ([[thread.req.lockable]](thread.req.lockable "32.2.5Requirements for Cpp17Lockable types")), then it is a [*timed waiting function*](#def:timed_waiting_function), otherwise
it is a [*non-timed waiting function*](#def:non-timed_waiting_function)[.](#3.sentence-3)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11335)
An [*asynchronous provider*](#def:asynchronous_provider "32.10.5Shared state[futures.state]") is an object that provides a result to a shared
state[.](#4.sentence-1)
The result of a shared state is set by
respective functions on the asynchronous provider[.](#4.sentence-2)
[*Example [1](#example-1)*:
Promises and tasks are examples of asynchronous providers[.](#4.sentence-3)
— *end example*]
The means of setting the result of a shared state is specified
in the description of those classes and functions that create such a state object[.](#4.sentence-4)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11346)
When an asynchronous return object or an asynchronous provider is said to release its
shared state, it means:
- [(5.1)](#5.1)
if the return object or provider holds the last reference to its shared state,
the shared state is destroyed; and
- [(5.2)](#5.2)
the return object or provider gives up its reference to its shared state; and
- [(5.3)](#5.3)
these actions will not block for the shared state to become ready, except that it
may block if all of the following are true: the shared state was created by a call tostd::async, the shared state is not yet ready, and this was the last reference
to the shared state[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11363)
When an asynchronous provider is said to make its shared state ready, it means:
- [(6.1)](#6.1)
first, the provider marks its shared state as ready; and
- [(6.2)](#6.2)
second, the provider unblocks any execution agents waiting for its shared
state to become ready[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11373)
When an asynchronous provider is said to abandon its shared state, it means:
- [(7.1)](#7.1)
first, if that state is not ready, the provider
* [(7.1.1)](#7.1.1)
stores an exception object of type future_error with an error condition ofbroken_promise within its shared state; and then
* [(7.1.2)](#7.1.2)
makes its shared state ready;
- [(7.2)](#7.2)
second, the provider releases its shared state[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11389)
A shared state is [*ready*](#def:ready "32.10.5Shared state[futures.state]") only if it holds a value or an exception ready for
retrieval[.](#8.sentence-1)
Waiting for a shared state to become ready may invoke code to compute the result on
the waiting thread if so specified in the description of the class or function that creates
the state object[.](#8.sentence-2)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11396)
Calls to functions that successfully set the stored result of a shared
state [synchronize with](intro.multithread#def:synchronize_with "6.10.2Multi-threaded executions and data races[intro.multithread]") calls to functions
successfully detecting the ready state resulting from that setting[.](#9.sentence-1)
The storage of the result
(whether normal or exceptional) into the shared state[synchronizes with](intro.multithread#def:synchronize_with "6.10.2Multi-threaded executions and data races[intro.multithread]") the successful return from a call to a waiting function on the shared state[.](#9.sentence-2)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11405)
Some functions (e.g., promise::set_value_at_thread_exit) delay making
the shared state ready until the calling thread exits[.](#10.sentence-1)
The destruction of
each of that thread's objects with [thread storage duration](basic.stc.thread "6.8.6.3Thread storage duration[basic.stc.thread]") is sequenced before making that shared state ready[.](#10.sentence-2)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11411)
Access to the result of the same shared state may [conflict](intro.multithread#def:conflict "6.10.2Multi-threaded executions and data races[intro.multithread]")[.](#11.sentence-1)
[*Note [3](#note-3)*:
This explicitly specifies that the result of the shared state is
visible in the objects that reference this state in the sense of data race
avoidance ([[res.on.data.races]](res.on.data.races "16.4.6.10Data race avoidance"))[.](#11.sentence-2)
For example, concurrent accesses through
references returned by shared_future::get() ([[futures.shared.future]](futures.shared.future "32.10.8Class template shared_­future"))
must either use read-only operations or provide additional synchronization[.](#11.sentence-3)
— *end note*]