std:: atomic <std::shared_ptr>
|
Definiert im Header
<memory>
|
||
|
template
<
class
T
>
struct std:: atomic < std:: shared_ptr < T >> ; |
(seit C++20) | |
Die partielle Template-Spezialisierung von
std::atomic
für
std::
shared_ptr
<
T
>
ermöglicht es Benutzern,
shared_ptr
-Objekte atomar zu manipulieren.
Wenn mehrere Ausführungsstränge auf dasselbe std::shared_ptr -Objekt ohne Synchronisierung zugreifen und einer dieser Zugriffe eine nicht-konstante Memberfunktion von shared_ptr verwendet, tritt ein Datenwettlauf auf, es sei denn, alle derartigen Zugriffe erfolgen über eine Instanz von std:: atomic < std:: shared_ptr > (oder, veraltet seit C++20, über die eigenständigen Funktionen für atomaren Zugriff auf std::shared_ptr ).
Assoziierte
use_count
-Inkremente sind garantiert Teil der atomaren Operation. Assoziierte
use_count
-Dekremente sind nach der atomaren Operation sequenziert, müssen jedoch nicht Teil davon sein, außer bei der
use_count
-Änderung beim Überschreiben von
expected
in einer fehlgeschlagenen CAS-Operation. Jede assoziierte Löschung und Freigabe ist nach dem atomaren Aktualisierungsschritt sequenziert und nicht Teil der atomaren Operation.
Beachten Sie, dass der Kontrollblock eines
shared_ptr
threadsicher ist: verschiedene nicht-atomare
std::shared_ptr
Objekte können mit veränderbaren Operationen, wie
operator
=
oder
reset
, gleichzeitig von mehreren Threads aus zugänglich sein, selbst wenn diese Instanzen Kopien sind und intern denselben Kontrollblock teilen.
Der Typ T kann ein unvollständiger Typ sein.
Mitgliedertypen
| Mitgliedstyp | Definition |
value_type
|
std:: shared_ptr < T > |
Memberfunktionen
Alle nicht-spezialisierten std::atomic Funktionen werden auch von dieser Spezialisierung bereitgestellt, und es gibt keine zusätzlichen Member-Funktionen.
|
constexpr
atomic
(
)
noexcept
=
default
;
|
(1) | |
|
constexpr
atomic
(
std::
nullptr_t
)
noexcept
:
atomic
(
)
{
}
|
(2) | |
|
atomic
(
std::
shared_ptr
<
T
>
desired
)
noexcept
;
|
(3) | |
|
atomic
(
const
atomic
&
)
=
delete
;
|
(4) | |
|
void
operator
=
(
const
atomic
&
)
=
delete
;
|
(1) | |
|
void
operator
=
(
std::
shared_ptr
<
T
>
desired
)
noexcept
;
|
(2) | |
|
void
operator
=
(
std::
nullptr_t
)
noexcept
;
|
(3) | |
|
bool
is_lock_free
(
)
const
noexcept
;
|
||
Gibt true zurück, wenn die atomaren Operationen auf allen Objekten dieses Typs sperrfrei sind, false andernfalls.
|
void
store
(
std::
shared_ptr
<
T
>
desired,
std:: memory_order order = std:: memory_order_seq_cst ) noexcept ; |
||
Ersetzt atomar den Wert von * this mit dem Wert von desired wie durch p. swap ( desired ) , wobei p der zugrundeliegende std:: shared_ptr < T > ist. Der Speicherzugriff wird gemäß order geordnet. Das Verhalten ist undefiniert, wenn order std::memory_order_consume , std::memory_order_acquire oder std::memory_order_acq_rel ist.
|
std::
shared_ptr
<
T
>
load
(
std::
memory_order
order
=
std::
memory_order_seq_cst
)
const
noexcept
;
|
||
Gibt atomar eine Kopie des zugrundeliegenden Shared Pointers zurück. Der Speicherzugriff wird gemäß order geordnet. Das Verhalten ist undefiniert, wenn order std::memory_order_release oder std::memory_order_acq_rel ist.
|
std::
shared_ptr
<
T
>
exchange
(
std::
shared_ptr
<
T
>
desired,
std:: memory_order order = std:: memory_order_seq_cst ) noexcept ; |
||
Ersetzt atomar den zugrundeliegenden std:: shared_ptr < T > mit desired wie durch p. swap ( desired ) wobei p der zugrundeliegende std:: shared_ptr < T > ist und gibt eine Kopie des Wertes zurück, den p unmittelbar vor dem Austausch hatte. Der Speicherzugriff wird gemäß order geordnet. Dies ist eine atomare Lese-Modifizier-Schreib-Operation.
|
bool
compare_exchange_strong
(
std::
shared_ptr
<
T
>
&
expected,
std::
shared_ptr
<
T
>
desired,
std:: memory_order success, std:: memory_order failure ) noexcept ; |
(1) | |
|
bool
compare_exchange_weak
(
std::
shared_ptr
<
T
>
&
expected,
std::
shared_ptr
<
T
>
desired,
std:: memory_order success, std:: memory_order failure ) noexcept ; |
(2) | |
|
bool
compare_exchange_strong
(
std::
shared_ptr
<
T
>
&
expected,
std::
shared_ptr
<
T
>
desired,
std:: memory_order order = std:: memory_order_seq_cst ) noexcept ; |
(3) | |
|
bool
compare_exchange_weak
(
std::
shared_ptr
<
T
>
&
expected,
std::
shared_ptr
<
T
>
desired,
std:: memory_order order = std:: memory_order_seq_cst ) noexcept ; |
(4) | |
/
/
use_count
von
expected
ist Teil dieser atomaren Operation, obwohl der Schreibvorgang selbst (und jede nachfolgende Freigabe/Zerstörung) nicht zwingend atomar sein muss.
fail_order
gleich
order
ist, außer dass
std::memory_order_acq_rel
ersetzt wird durch
std::memory_order_acquire
und
std::memory_order_release
ersetzt wird durch
std::memory_order_relaxed
.
fail_order
gleich
order
ist, außer dass
std::memory_order_acq_rel
ersetzt wird durch
std::memory_order_acquire
und
std::memory_order_release
ersetzt wird durch
std::memory_order_relaxed
.
|
void
wait
(
std::
shared_ptr
<
T
>
old,
std:: memory_order order = std:: memory_order_seq_cst ) const noexcept ; |
||
Führt eine atomare Warteoperation aus.
Vergleicht
load
(
order
)
mit
old
und blockiert, falls sie äquivalent sind, bis
*
this
durch
notify_one()
oder
notify_all()
benachrichtigt wird. Dies wird wiederholt, bis sich
load
(
order
)
ändert. Diese Funktion gibt garantiert nur zurück, wenn sich der Wert geändert hat, selbst wenn die zugrunde liegende Implementierung fälschlicherweise entblockt.
Der Speicherzugriff wird gemäß order geordnet. Das Verhalten ist undefiniert, wenn order std::memory_order_release oder std::memory_order_acq_rel ist.
Hinweis: Zwei
shared_ptr
s sind äquivalent, wenn sie denselben Zeiger speichern und entweder gemeinsamen Besitz teilen oder beide leer sind.
|
void
notify_one
(
)
noexcept
;
|
||
Führt eine atomare Benachrichtigungsoperation aus.
Falls ein Thread in atomaren Wartevorgängen (d.h.
wait()
) auf
*
this
blockiert ist, wird mindestens ein solcher Thread entblockiert; andernfalls geschieht nichts.
|
void
notify_all
(
)
noexcept
;
|
||
Führt eine atomare Benachrichtigungsoperation durch.
Entsperrt alle Threads, die in atomaren Warteoperationen (d.h.
wait()
) auf
*
this
blockiert sind, falls vorhanden; andernfalls tut es nichts.
Memberkonstanten
Die einzige standardmäßige
std::atomic
Member-Konstante
is_always_lock_free
wird ebenfalls von dieser Spezialisierung bereitgestellt.
|
static
constexpr
bool
is_always_lock_free
=
/*implementierungsdefiniert*/
;
|
||
Hinweise
| Feature-Test Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_lib_atomic_shared_ptr
|
201711L
|
(C++20) |
std::atomic<std::shared_ptr>
|
Beispiel
|
Dieser Abschnitt ist unvollständig
Grund: Kein Beispiel |
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| LWG 3661 | C++20 |
atomic<shared_ptr<T>>
war nicht konstant-initialisierbar von
nullptr
|
konstant-initialisierbar gemacht |
| LWG 3893 | C++20 |
LWG3661
machte
atomic<shared_ptr<T>>
nicht zuweisbar von
nullptr_t
|
Zuweisbarkeit wiederhergestellt |
Siehe auch
|
(C++11)
|
Atomic-Klassen-Template und Spezialisierungen für bool, Ganzzahl,
Gleitkomma,
(seit C++20)
und Zeigertypen
(Klassen-Template) |