C ++ Smart Zeiger und Speichermodell: Warum werden Inkremente nicht mit Dekrementen im Steuerblock synchronisiert?C++

Programme in C++. Entwicklerforum
Guest
 C ++ Smart Zeiger und Speichermodell: Warum werden Inkremente nicht mit Dekrementen im Steuerblock synchronisiert?

Post by Guest »

Ich habe diese Frage untersucht. Wie kann „memory_order_relaxed“ für die Erhöhung der Anzahl atomarer Referenzen in intelligenten Zeigern funktionieren? Hier noch einmal der Codeausschnitt:

Code: Select all

// Thread A:
// smart_ptr copy ctor
smart_ptr(const smart_ptr& other) {
...
control_block_ptr = other->control_block_ptr;
control_block_ptr->refs.fetch_add(1, memory_order_relaxed);
...
}

// Thread D:
// smart_ptr destructor
~smart_ptr() {
if (control_block_ptr->refs.fetch_sub(1, memory_order_acq_rel) == 1) {
delete control_block_ptr;
}
}
Ich verstehe immer noch nicht, warum wir „memory_order_relaxed“ für das Inkrement haben können.
Eine der Antworten liefert den Auszug:

Das Erhöhen des Referenzzählers kann immer mit „memory_order_relaxed“ erfolgen: Neue Referenzen auf ein Objekt können nur aus einer vorhandenen Referenz gebildet werden und eine vorhandene Referenz von einem Thread an einen anderen übergeben muss bereits alles Erforderliche bereitstellen Synchronisierung.

Außerdem habe ich den Link https://gavinchou.github.io/summary/c++ ... -ordering/ gefunden, wo es geschrieben steht :

Inkrement kann gelockert werden (keine Veröffentlichungsoperation, niemand ist auf dieses Inkrement angewiesen).
Diese Absätze implizieren, dass diese Erhöhungen sind irgendwie unabhängig, und hier https://en.cppreference.com/w/cpp/atomic/memory_order wird erklärt, dass eine lockere Speicherreihenfolge für (unabhängige) Inkremente in Ordnung ist.
Allerdings Im obigen Beispiel sind die Inkremente überhaupt nicht unabhängig. Es gibt auch gleichzeitige Dekremente, die von den Inkrementen abhängen (wenn der gelesene Wert 1 ist, wird das Objekt gelöscht). Die Inkremente werden gelockert, sodass die Dekremente sie möglicherweise nicht sehen und das Objekt löschen. Auch wenn wir bedenken, dass RMW-Operationen immer den neuesten Wert lesen, ist die Reihenfolge der Inkremente/Dekremente, die von verschiedenen Threads gesehen werden, immer noch unterschiedlich, sodass nicht klar ist, was ein dekrementierender Thread sehen wird.
Ist Ist das kein Problem und sollten die Inkremente nicht irgendwie mit den Dekrementen synchronisiert werden? Kann die beiden Erklärungen oben leider nicht verstehen: Sie sind zu kurz.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post