Namensräume
Varianten
Aktionen

std::atomic<std::shared_ptr>

Von cppreference.com
< cpp‎ | memory‎ | shared ptr
 
 
Speicherverwaltungsbibliothek
(nur Exposition*)
Algorithmen für uninitialisierten Speicher
(C++17)
(C++17)
(C++17)
Beschränkte uninitialisierte
Speicher-Algorithmen
C-Bibliothek

Allocatoren
Speicherressourcen
Unterstützung für Garbage Collection
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
Uninitialisierter Speicher
Explizites Lebenszeitmanagement
 
 
Definiert in 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 Benutzern die atomare Manipulation von shared_ptr-Objekten.

Wenn mehrere Ausführungs-Threads ohne Synchronisation auf dasselbe std::shared_ptr-Objekt zugreifen und einer dieser Zugriffe eine nicht-konstante Member-Funktion von shared_ptr verwendet, tritt ein Datenrennen auf, es sei denn, alle solchen Zugriffe erfolgen über eine Instanz von std::atomic<std::shared_ptr> (oder, seit C++20 als veraltet markiert, über die eigenständigen Funktionen für den atomaren Zugriff auf std::shared_ptr).

Inkremente des zugehörigen use_count sind garantiert Teil der atomaren Operation. Dekremente des zugehörigen use_count werden nach der atomaren Operation sequenziert, sind aber nicht Teil davon erforderlich, außer bei der Änderung von use_count beim Überschreiben von expected in einem fehlgeschlagenen CAS. Jegliche zugehörige Löschung und Deallokation werden nach dem atomaren Update-Schritt sequenziert und sind kein Teil der atomaren Operation.

Beachten Sie, dass der Kontrollblock eines shared_ptr threadsicher ist: verschiedene nicht-atomare std::shared_ptr-Objekte können gleichzeitig von mehreren Threads über veränderliche Operationen wie operator= oder reset zugegriffen werden, auch wenn diese Instanzen Kopien sind und intern denselben Kontrollblock teilen.

Der Typ T darf ein unvollständiger Typ sein.

Inhalt

[edit] Member types

Mitgliedertyp Definition
value_type std::shared_ptr<T>

[edit] Member functions

Alle nicht spezialisierten std::atomic-Funktionen werden auch von dieser Spezialisierung bereitgestellt, und keine zusätzlichen Member-Funktionen.

atomic<shared_ptr<T>>::atomic

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)
1,2) Initialisiert den zugrunde liegenden shared_ptr<T> zum Nullwert.
3) Initialisiert den zugrunde liegenden shared_ptr<T> mit einer Kopie von desired. Wie bei jedem std::atomic-Typ ist die Initialisierung keine atomare Operation.
4) Atomare Typen sind nicht kopier- oder verschiebbar konstruierbar.

atomic<shared_ptr<T>>::operator=

void operator=( const atomic& ) = delete;
(1)
void operator=( std::shared_ptr<T> desired ) noexcept;
(2)
void operator=( std::nullptr_t ) noexcept;
(3)
1) Atomare Typen sind nicht kopier- oder verschiebbar zuweisbar.
2) Wertzuweisung, äquivalent zu store(desired).
3) Setzt den atomaren Shared Pointer auf einen Nullzeigerwert zurück. Äquivalent zu store(nullptr);.

atomic<shared_ptr<T>>::is_lock_free

bool is_lock_free() const noexcept;

Gibt true zurück, wenn die atomaren Operationen auf allen Objekten dieses Typs sperrfrei sind, andernfalls false.

atomic<shared_ptr<T>>::store

void store( std::shared_ptr<T> desired,
            std::memory_order order = std::memory_order_seq_cst ) noexcept;

Ersetzt atomar den Wert von *this durch den Wert von desired, als ob p.swap(desired) ausgeführt würde, wobei p der zugrunde liegende std::shared_ptr<T> ist. Der Speicher 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.

atomic<shared_ptr<T>>::load

Gibt atomar eine Kopie des zugrunde liegenden Shared Pointers zurück. Der Speicher wird gemäß order geordnet. Das Verhalten ist undefiniert, wenn order std::memory_order_release oder std::memory_order_acq_rel ist.

atomic<shared_ptr<T>>::operator std::shared_ptr<T>

operator std::shared_ptr<T>() const noexcept;

Äquivalent zu return load();.

atomic<shared_ptr<T>>::exchange

std::shared_ptr<T> exchange( std::shared_ptr<T> desired,
                             std::memory_order order = std::memory_order_seq_cst ) noexcept;

Ersetzt atomar den zugrunde liegenden std::shared_ptr<T> durch desired, als ob p.swap(desired) ausgeführt würde, wobei p der zugrunde liegende std::shared_ptr<T> ist, und gibt eine Kopie des Wertes zurück, den p unmittelbar vor dem Tausch hatte. Der Speicher wird gemäß order geordnet. Dies ist eine atomare Lese-Modifikations-Schreib-Operation.

atomic<shared_ptr<T>>::compare_exchange_weak, compare_exchange_strong

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)
1) Wenn der zugrunde liegende std::shared_ptr<T> denselben T* wie expected speichert und den Besitz mit ihm teilt, oder wenn beide, der zugrunde liegende und expected, leer sind, wird von desired in den zugrunde liegenden std::shared_ptr<T> zugewiesen, true zurückgegeben und der Speicher gemäß success geordnet. Andernfalls wird vom zugrunde liegenden std::shared_ptr<T> nach expected zugewiesen, false zurückgegeben und der Speicher gemäß failure geordnet. Das Verhalten ist undefiniert, wenn failure std::memory_order_release oder std::memory_order_acq_rel ist. Bei Erfolg ist die Operation eine atomare Lese-Modifikations-Schreib-Operation auf *this und expected wird nach dem atomaren Update nicht mehr zugegriffen. Bei Fehlschlag ist die Operation eine atomare Ladeoperation auf *this und expected wird mit dem aktuellen Wert aus dem atomaren Objekt aktualisiert. Diese Aktualisierung von expected's use_count ist Teil dieser atomaren Operation, obwohl die Schreiboperation selbst (und jede nachfolgende Deallokation/Zerstörung) nicht erforderlich ist.
2) Identisch mit (1), kann aber auch fehlerhaft fehlschlagen.
3) Äquivalent zu: return compare_exchange_strong(expected, desired, order, fail_order);, wobei fail_order dasselbe ist wie order, außer dass std::memory_order_acq_rel durch std::memory_order_acquire ersetzt wird und std::memory_order_release durch std::memory_order_relaxed ersetzt wird.
4) Äquivalent zu: return compare_exchange_weak(expected, desired, order, fail_order);, wobei fail_order dasselbe ist wie order, außer dass std::memory_order_acq_rel durch std::memory_order_acquire ersetzt wird und std::memory_order_release durch std::memory_order_relaxed ersetzt wird.

atomic<shared_ptr<T>>::wait

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, wenn sie äquivalent sind, bis *this durch notify_one() oder notify_all() benachrichtigt wird. Dies wird wiederholt, bis sich load(order) ändert. Diese Funktion kehrt garantiert nur dann zurück, wenn sich der Wert geändert hat, auch wenn die zugrunde liegende Implementierung fälschlicherweise entsperrt.

Der Speicher wird gemäß order geordnet. Das Verhalten ist undefiniert, wenn order std::memory_order_release oder std::memory_order_acq_rel ist.

Hinweis: Zwei shared_ptrs sind äquivalent, wenn sie denselben Zeiger speichern und entweder den Besitz teilen oder beide leer sind.

atomic<shared_ptr<T>>::notify_one

void notify_one() noexcept;

Führt eine atomare Benachrichtigungsoperation aus.

Wenn ein Thread in atomaren Warteoperationen (d.h. wait()) auf *this blockiert ist, dann werden mindestens ein solcher Thread entsperrt; andernfalls tut sie nichts.

atomic<shared_ptr<T>>::notify_all

void notify_all() noexcept;

Führt eine atomare Benachrichtigungsoperation aus.

Entsperrt alle Threads, die in atomaren Warteoperationen (d.h. wait()) auf *this blockiert sind, falls vorhanden; andernfalls tut sie nichts.

[edit] Member constants

Die einzige Standard std::atomic-Member-Konstante is_always_lock_free wird ebenfalls von dieser Spezialisierung bereitgestellt.

atomic<shared_ptr<T>>::is_always_lock_free

static constexpr bool is_always_lock_free = /*implementierungsdefiniert*/;

[edit] Notes

Feature-Test-Makro Wert Std Feature
__cpp_lib_atomic_shared_ptr 201711L (C++20) std::atomic<std::shared_ptr>

[edit] Example

[edit] Defect reports

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 aus nullptr konstant initialisierbar gemacht
LWG 3893 C++20 LWG3661 machte atomic<shared_ptr<T>> nicht von nullptr_t zuweisbar Zuweisbarkeit wiederhergestellt

[edit] See also

(C++11)
atomares Klassentemplate und Spezialisierungen für boolesche, integrale, Gleitkomma-(seit C++20) und Zeigertypen
(Klassen-Template) [bearbeiten]