Frage

Wie setzen Sie eine effiziente und sichere Referenz Zählsystem Gewinde auf X86 CPUs in der Programmiersprache C ++?

ich immer in das Problem führen, dass die kritischen Operationen nicht atomar , und die zur Verfügung stehenden X86 Verriegelungs-Operationen nicht ausreicht, um die ref Zählsystem für die Umsetzung.

Der folgende Artikel behandelt das Thema, sondern erfordert eine spezielle CPU-Anweisungen:

http://www.ddj.com/architect/184401888

War es hilfreich?

Lösung

Heute können Sie die Anhebung / TR1 shared_ptr <> Smart-Pointer verwenden, um Ihre Referenz gezählt Referenzen zu halten.

Arbeiten groß; kein Getue, kein Durcheinander. Die shared_ptr <> Klasse kümmert sich um alle die Verriegelung am refcount benötigt.

Andere Tipps

In VC ++, können Sie _InterlockedCompareExchange .

do
   read the count
   perform mathematical operation
   interlockedcompareexchange( destination, updated count, old count)
until the interlockedcompareexchange returns the success code.

Auf anderen Plattformen / Compiler, verwenden Sie die entsprechende Eigen für die LOCK cmpxchg Anweisung, die MS die _InterlockedCompareExchange aussetzt.

Genau genommen, werden Sie bis C ++ 0x warten müssen, um der Lage sein, Thread-sicher Code in reinem C ++ zu schreiben.

Für jetzt können Sie Posix verwenden, oder erstellen Sie eigene plattformunabhängige Wrapper um Vergleichs- und Auslagerungs und / oder verzahnt Inkrement / Dekrement.

Win32 InterlockedIncrementAcquire und InterlockedDecrementRelease (wenn Sie sicher sein wollen, und kümmern sich um Plattformen mit möglicher Umordnung, daher müssen Sie Speicher Barrieren zur gleichen Zeit zur Ausgabe) oder InterlockedIncrement und InterlockedDecrement (wenn Sie sicher sind, bleiben Sie x86), ist Atom- und wird die Arbeit machen.

Wie gesagt, Anhebung / TR1 shared_ptr <> wird für Sie alle damit umgehen, also, wenn Sie es auf eigene Faust implementieren müssen, werden Sie wahrscheinlich das Beste tun, um es zu halten.

Beachten Sie, dass die Verriegelung ist sehr teuer, und es passiert jedes Mal, wenn Sie die Hand um Objekte zwischen Smart-Pointer -. Selbst wenn das Objekt gerade von einem Thread (die Smart-Pointer-Bibliothek nicht weiß, dass) gehört

Diese Da kann es eine Faustregel gilt: hier anwendbar sein (ich bin glücklich korrigiert zu werden!)

Wenn die Folge Dinge auf Sie zutrifft:

  • Sie haben komplexe Datenstrukturen, die schwierig sein würde, Destruktoren für (oder wo STL-Stil Wert Semantik wäre unangemessen, von Design) zu schreiben, so brauchen Sie intelligente Zeiger um es für Sie zu tun, und
  • Sie verwenden mehrere Threads, die diese Objekte teilen, und
  • Sie kümmern sowie Korrektheit über die Leistung

... dann tatsächlich Garbage Collection kann eine bessere Wahl sein. Obwohl GC einen schlechten Ruf für die Leistung hat, es ist alles relativ. Ich glaube, es mit Verriegelungs Smart-Pointer sehr günstig vergleicht. Es war ein wichtiger Teil, warum das CLR-Team wahr GC anstatt etwas mit Referenzzählung gewählt hat. Siehe dieser Artikel , insbesondere diese krassen Vergleich dessen, was Referenzzuordnung bedeutet, wenn Sie haben zu zählen los:

keine ref Zählung:

a = b;

ref Zählung:

if (a != null)
    if (InterlockedDecrement(ref a.m_ref) == 0)
            a.FinalRelease();

if (b != null)
    InterlockedIncrement(ref b.m_ref);

a = b;

Wenn der Befehl selbst nicht atomar ist, dann müssen Sie den Abschnitt des Codes machen, dass die entsprechende Variable einen kritischen Abschnitt aktualisiert.

d. Sie müssen andere Threads verhindern, dass die Code-Abschnitts Eingabe durch ein Sperrschema verwenden. Natürlich sind die Schleusen Atom sein müssen, aber Sie können einen atomaren Verriegelungsmechanismus innerhalb der pthread_mutex Klasse finden.

Die Frage der effizienten:. Die pthread-Bibliothek so effizient ist, wie es sein kann und garantiert immer noch, dass Mutex-Sperre für Ihr O Atom ist

Ist es teuer: Wahrscheinlich. Aber für alles, was eine Garantie erfordert es eine Kosten.

Dieser spezielle Code in diesem ddj Beitrag geschrieben wird das Hinzufügen zusätzlicher Aufwand für die Fehler erklären Sie sich mit der Smart-Pointer.

Insbesondere wenn Sie nicht, dass die Smart-Pointer garantieren können, nicht auf einem anderen intelligenten Zeiger in einer Zuweisung ändern, Sie tun es falsch oder mit etwas sehr unzuverlässig zu beginnen tun. Wenn der Smart-Pointer, während sie zugewiesen zu einem anderen Smart-Pointer ändern können, das bedeutet, dass der Code die Zuordnung zu tun besitzen nicht die Smart-Pointer, der Verdächtige zu beginnen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top