Muss ich den Lesezugriff auf einen STL-Container in einer Multithreading-Umgebung schützen?

8

Ich habe eine std :: list & lt; & gt; Container und diese Threads:

  • Ein Autorenthread, der Elemente auf unbestimmte Zeit hinzufügt.

  • Ein Reader / Writer-Thread, der Elemente liest und entfernt, solange sie verfügbar sind.

  • Mehrere Reader-Threads, die auf die GRÖSSE des Containers zugreifen (durch Verwendung der size () -Methode)

Es gibt einen normalen Mutex, der den Zugriff auf die Liste von den ersten beiden Threads schützt. Meine Frage ist, müssen die Größe Leser Threads diesen Mutex auch erwerben? Soll ich einen Lese- / Schreib-Mutex verwenden?

Ich bin in einer Windows-Umgebung mit Visual C ++ 6.

Update : Die Antwort ist noch nicht klar. Um den Hauptbezweifeln zusammenzufassen: Muss ich die SIZE Reader Threads auch dann schützen, wenn sie nur size () aufrufen (was eine einfache Variable zurückgibt), die berücksichtigt, dass ich nicht den genauen Wert benötige (dh ich kann a annehmen +/- 1 Variation)? Wie kann eine Race-Bedingung meinen Aufruf von size () dazu bringen, einen ungültigen Wert zurückzugeben (d. H. Einen, der überhaupt nichts mit dem guten zu tun hat)?

Antwort : Im Allgemeinen müssen die Leser-Threads geschützt werden, um Race-Bedingungen zu vermeiden. Meiner Meinung nach wurden einige der oben genannten Fragen im Update noch nicht beantwortet.

Vielen Dank im Voraus!

Vielen Dank für Ihre Antworten!

    
David Alfonso 09.10.2008, 14:47
quelle

8 Antworten

10

Ja, die Lese-Threads benötigen eine Art Mutex-Kontrolle, sonst wird der Schreibvorgang die darunter liegenden Dinge ändern.

Ein Lese- / Schreib-Mutex sollte ausreichen. Genau genommen handelt es sich jedoch um ein implementationsspezifisches Problem. Es ist möglich, dass eine Implementierung auch in konstanten Objekten, die in Ihrem Code schreibgeschützt sind, änderbare Mitglieder haben kann.

    
Michael Burr 09.10.2008, 14:49
quelle
2

Überprüfen Sie die gleichzeitigen Container, die von der Threading Building Blocks Bibliothek von Intel zur Verfügung gestellt werden. Suchen Sie unter "Container-Snippets" auf der Seite mit den Codebeispielen für einige Beispiele. Sie haben gleichzeitige / Thread-sichere Container für Vektoren, Hash-Maps und Warteschlangen.

    
Pat Notz 09.10.2008 15:18
quelle
1

Ich glaube nicht, dass die STL-Container Thread-sicher sind, da es keine gute Möglichkeit gibt, Threads plattformübergreifend zu behandeln. Der Aufruf von size () ist einfach, muss aber trotzdem geschützt werden.

Das klingt wie ein großartiger Ort, um Lese-Schreib-Sperren zu verwenden.

    
Herms 09.10.2008 14:50
quelle
1

Sie sollten bedenken, dass eine SLT-Implementierung die Größe beim Aufruf möglicherweise berechnet berechnet.
Um dies zu umgehen, könnten Sie eine neue Variable definieren

%Vor%

Aktualisieren Sie die Variable nur in bereits geschützten Update-Aufrufen, aber Sie können die Variable ohne Schutz lesen / testen (unter Berücksichtigung, dass Sie nicht den genauen Wert benötigen).

    
Tal 28.10.2008 10:01
quelle
0

Ja. Ich würde vorschlagen, Ihre STL-Bibliothek mit einer Klasse zu versehen, die den seriellen Zugriff erzwingt. Oder finden Sie eine ähnliche Klasse, die bereits debuggt wurde.

    
Paul Nathan 09.10.2008 14:51
quelle
0

Ich werde nein sagen. In diesem Fall.

Ohne einen Mutex könnten Sie feststellen, dass die Größe () gelegentlich den falschen Wert zurückgibt, wenn Elemente hinzugefügt oder entfernt werden. Wenn dies für Sie akzeptabel ist, gehen Sie dafür.

Wenn Sie jedoch die genaue Größe der Liste benötigen, wenn der Leser sie kennen muss, müssen Sie zusätzlich zu dem, den Sie um die Anrufe hinzufügen und löschen haben, einen kritischen Abschnitt um jede Größe einfügen.

PS. VC6 size () gibt einfach das interne Element _Size zurück, so dass kein Mutex kein Problem mit Ihrer speziellen Implementierung ist, außer dass es 1 zurückgibt, wenn ein zweites Element hinzugefügt wird oder umgekehrt.

PPS. Jemand erwähnte eine RW-Sperre, das ist eine gute Sache, besonders wenn Sie versucht sind, später auf die Listenobjekte zuzugreifen. Ändern Sie Ihren Mutex zu einem Boost :: shared_mutex wäre dann von Vorteil. Es wird jedoch kein Mutex benötigt, wenn Sie nur die Größe () aufrufen.

    
gbjbaanb 09.10.2008 15:04
quelle
0

Die STL in VC ++ Version 6 ist nicht Thread-sicher, siehe diese letzte Frage . So scheint es, deine Frage ist ein bisschen irrelevant. Selbst wenn Sie alles richtig gemacht haben, können Sie immer noch Probleme haben.

    
MSalters 10.10.2008 15:05
quelle
0

Ob size () sicher ist (für die Definition von "safe", die Sie angeben), ist implementierungsabhängig. Auch wenn Sie auf Ihrer Plattform abgedeckt sind, für Ihre Version Ihres Compilers auf Ihrer Optimierungsstufe für Ihre Version der Thread-Bibliothek und C-Laufzeit, bitte kodieren Sie nicht auf diese Weise. Es kommt zurück zu Byte Sie, und es wird die Hölle zu debuggen. Du bringst dich zum Scheitern.

    
Arkadiy 29.10.2008 03:09
quelle