2 Stimmen

C++-Version von CopyOnWriteArrayList

Java hat CopyOnWriteArrayList die es mir ermöglicht, mit 2 verschiedenen Threads gleichzeitig zu iterieren und zu mutieren, ohne dass eine externe Sperre erforderlich ist.

Gibt es eine ähnliche Thread-Safety-Datenstruktur für C++?

3voto

James Kanze Punkte 146902

In der Standardbibliothek gibt es nichts, was dies unterstützen würde. Angesichts der Schnittstelle zu C++-Standardcontainern bin ich mir nicht sicher, ob es möglich ist. Sie müssten mit etwas wie beginnen:

template <typename T>
class CopyOnWriteVector
{
    boost::shared_ptr<std::vector<T> > myData;
    void uniqueCopy()
    {
        myData = boost::shared_ptr<std::vector<T> >( new std::vector<T>( *myData ) );
    }
public:
    //  ...
    //  for example...
    void push_back( T const& newElement )
    {
        uniqueCopy();
        myData->push_back( newElement );
    }
    //  Similar for all other non-const functions.
    //  const functions just forward, without the call to
    uniqueCopy.
};

Dies funktioniert jedoch nicht bei Funktionen, die Handles zu einigen internen Daten zurückgeben: entweder Iteratoren oder Referenzen auf Elemente. Für Iteratoren wäre es möglich, einen Iterator zu erstellen, der a shared_ptr auf den Container, in den es sich wiederholt, z. B.:

template <typename T>
class CopyOnWriteVector
{
    //  ...
public:
    class iterator : public std::random_access_iterator_tag
    {
        boost::shared_ptr<std::vector<T> > myVector;
        typename std::vector<T>::iterator myImpl;
    public:
        iterator() {}  //  for convenience...
        iterator( boost::shared_ptr<std::vector<T> > const& vector,
                  typename std::vector<T>::iterator initialValue )
            : myVector( vector )
            , myImpl( initialValue )
        {
        }
        //  All other iterator functions forward directly to myImpl
    };
};

Die Funktionen, die Referenzen zurückgeben, sind ein anderes Thema; Sie können nicht Referenz nicht durch eine intelligente Referenz oder einen Proxy beliebigen Typs ersetzen.

(Hinweis: Der gesamte obige Code ist mir gerade erst eingefallen und enthält wahrscheinlich erhebliche Fehler. Er soll nur eine Vorstellung davon vermitteln, in welche Richtung Sie gehen könnten).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X