Erstellen eines nicht threadsicheren shared_ptr

8

Ich arbeite an einem Multithread-Programm, habe aber eine UI-Komponente, die std :: shared_ptr zur Verwaltung von Elementen verwendet. Ich kann garantieren, dass nur ein Thread jemals diese shared_ptrs benutzen wird.

Gibt es eine Möglichkeit, ein shared_ptr zu definieren, das nicht den Overhead der Thread-sicheren Referenzzählung verursacht?

Es könnte auf boost :: shared_ptr oder std :: shared_ptr basieren.

EDIT: Danke für die Antworten, die intrusive_ptr erwähnen. Ich habe es versäumt zu erwähnen, dass ich auch die Funktion "weak_ptr" brauche, um das zu verhindern.

    
mpipe3 06.07.2011, 08:48
quelle

5 Antworten

3

Andrei Alexandrescu hat auf der CppCon 2014 über die Implementierung einer eigenen Shared-Pointer-Klasse mit einzelnen Threads (mit einigen zusätzlichen Optimierungen) gesprochen.

Sehen Sie das Video hier

Und die Folien hier

Ich denke wirklich, dass der Standard oder Boost einen Template-Parameter für die Verwendung von atomarem Ref-Zählen in ihren gemeinsamen PTRs liefern sollte, obwohl ...

    
onqtam 06.11.2014 09:33
quelle
3

Sie können intrusive_ptr verwenden, da Sie damit Ihre eigenen erstellen können Referenzzählung. Wenn diese Referenzzählung ein einfaches Inkrementieren / Dekrementieren einer Variablen ist, erhalten Sie wahrscheinlich keine bessere Leistung als diese.

    
stijn 06.07.2011 09:03
quelle
1

Ich habe einen Code, bei dem der Aufwand beim Kopieren von shared_ptr ein Problem geworden ist und zu diesem Zeitpunkt alternative Techniken verwendet haben. Lassen Sie mich zuerst feststellen, dass andere Kommentare richtig sind, dass der Overhead von shared_ptr sehr niedrig ist. Ich profilierte dies, um tatsächlich einen meiner Probleme zu finden. Auf meinem AMD64 Phenom, der eine Funktion aufruft, die das shared_ptr kopiert, dauert ungefähr 12ns gegen das Aufrufen der gleichen Funktion mit einem normalen Zeiger um ungefähr 1ns.

Angesichts dieser Zahlen ist es schwer vorstellbar, dass Sie irgendeine Art von "sicherer" Variante zwischen einem rohen Zeiger und der shared_ptr erhalten werden. Also, was ich in diesen Fällen mache, gebe ich entweder den tatsächlichen Zeiger oder ein const & an das shared_ptr weiter. Normalerweise lege ich eine Mutex-Sperre auf den gesamten Codebereich, damit ich die shared_ptr für die gesamte Dauer beibehalten kann. Sie könnten einen Singlethread-Referenzzähler handrollen, aber was wäre der Punkt, wenn Sie wissen, dass er nicht geteilt wird?

Aber bedenkt die Zeitpunkte sehr sorgfältig. Wenn Sie nicht die shared_ptr Tausende oder sogar Zehntausende Male pro Sekunde kopieren, werden Sie den Overhead von shared_ptr nicht bemerken.

Im GUI-Code des gleichen Projekts verwende ich immer shared_ptr, nur der Server-Code vermeidet es in einigen Schlüsselbereichen. Es gibt nur so viele andere Dinge in der GUI, die es verlangsamen: Vermeiden shared_ptr würde keinen nennenswerten Unterschied machen.

    
edA-qa mort-ora-y 06.07.2011 09:10
quelle
1

Ich schlage vor, mit dem intrusiven Smart Pointer von Boost zu gehen.

Es gibt auch eine Implementierung von Scott Meyer (hier: Ссылка ) wie in Effektiver C ++ "

Falls es jedoch hilft, habe ich einen einfachen Refcounting-Zeiger (mit etwas Unterstützung für polymorphe Zuweisungen und benutzerdefinierte Deletors) gezogen. Dieser ist entschlossen, unkenntlich zu machen .

  

Hinweis: Ich habe das falsch verstanden. Die polymorphen Anordnungen waren in einer Variation für ein anderes Projekt. Ich habe das auch, aber es unterstützt nicht die benutzerdefinierte deletor :) Lassen Sie mich wissen, wenn jemand interessiert ist; Natürlich kommt es mit separaten Komponententests für die Funktion

Es kommt mit Komponententests (z. B. um nach dem bekannten remove linked list node Ordnungsfehler zu suchen). Also weißt du was du bekommst:)

%Vor%

Komponententests (kompiliert als eigenständiges Programm)

%Vor%     
sehe 06.07.2011 09:22
quelle
0

Boost bietet ein Makro, das Sie definieren können, das keine thread-sichere Referenzzählung verwendet.

    
Puppy 06.07.2011 10:44
quelle

Tags und Links