Ist standardmäßig std :: vector threadsicher und gleichzeitig? Warum oder warum nicht?

7

Was bedeutet es, ein dynamisches Array threadsicher und gleichzeitig zu machen? Sagen Sie beispielsweise std::vector .

  1. Zwei Threads möchten möglicherweise an der gleichen Position eingefügt werden. Es ist keine Synchronisation erforderlich, da dies gemäß der Thread-Planung durchgeführt wird.
  2. Ein Thread wird gelöscht und ein anderer greift auf dasselbe Element zu? Dies ist kein Problem mit der Datenstruktur. Ich glaube, es ist ein Nutzungsproblem.

Gibt es also etwas, das über std::vector erledigt werden muss, um es threadsicher und gleichzeitig zu machen oder ist es threadsicher und gleichzeitig standardmäßig?

    
Abhishek Jain 30.06.2015, 07:07
quelle

2 Antworten

16

C ++ 11 sagt Folgendes über die Thread-Sicherheit von Containern in der Standardbibliothek:

  

23.2.2 Containerdatenrassen [container.requirements.dataraces]

     

Zum Zweck der Vermeidung von Datenrennen (17.6.5.9) müssen Implementierungen   Betrachte die folgenden Funktionen als const: begin , end ,    rbegin , rend , front , back , data , find , lower_bound ,    upper_bound , equal_range , at und, außer in assoziativen oder   ungeordnete assoziative Container, operator[] .

     

Ungeachtet (17.6.5.9) sind Implementierungen erforderlich, um Daten zu vermeiden   Rennen, wenn der Inhalt des enthaltenen Objekts in verschiedenen Elementen   in der gleichen Reihenfolge, mit Ausnahme von vector<bool> , werden geändert   gleichzeitig.

Das Lesen von einem Container aus mehreren Threads ist also in Ordnung, und das Modifizieren von Elementen, die sich bereits im Container befinden, ist in Ordnung (solange sie verschiedene Elemente sind).

Daher ist keine der beiden spezifischeren Fragen für std::vector threadsicher:

1) Zwei Threads, die in den Vektor eingefügt werden, modifizieren den Vektor selbst - keine existierenden separaten Elemente.

2) Das Löschen eines Threads und anderes Gehen, um auf dasselbe Element zuzugreifen, ist nicht sicher, da das Löschen eines Elements aus dem Vektor keine Operation ist, die threadsicher ist (oder "frei von Datenrennen" wie der Standard) setzt es).

Um diese Operationen sicher ausführen zu können, muss das Programm eine externe Synchronisation selbst vornehmen.

    
Michael Burr 30.06.2015 07:16
quelle
2

Die einzigen gleichzeitigen Operationen für ein einzelnes Objekt in der Standardbibliothek, die standardmäßig sicher sind, sind  - Nur Zugriff auf const -Member Funktionen  - Alle Zugriffe auf Synchronisationsprimitive (wie Mutex Lock und Unlock oder atomare Operationen) Alles andere muss extern synchronisiert werden. Insbesondere hat die Standardbibliothek noch keine threadsicheren Container (ab c ++ 14)

Die Antwort auf beide Beispiele ist also nein, beide erfordern eine Form der externen Synchronisation.

Sie können natürlich den Wert zweier verschiedener Elemente im Container ändern.

    
MikeMB 30.06.2015 07:34
quelle