2010-12-09 3 views
11

Ich benutze Android 2.2, das mit einer Version von STLport kommt. Aus irgendeinem Grund wurde es als nicht threadsicher konfiguriert. Dies wurde mithilfe eines #define _NOTHREADS in einer Konfigurationsheaderdatei durchgeführt.Ist C++ STL Thread-sicher für unterschiedliche Container (mit STLport-Implementierung)?

Als ich distinct non-shared Container (z. B. Strings) von verschiedenen Pthreads erstellt und initialisiert, bekam ich Speicherbeschädigung.

Mit _NOTHREADS, sieht es aus wie einige Low-Level-Code in STL innerhalb von allocator.cpp nicht ordnungsgemäßes Sperren. Es scheint analog zu C nicht Thread-Sicherheit für Malloc bereitzustellen.

Weiß jemand, warum STL möglicherweise mit _NOTHREADS standardmäßig auf Android gebaut wird? Wenn ich das deaktiviere, frage ich mich, ob es einen Nebeneffekt geben könnte. Eine Sache, an die ich denken kann, ist eine leicht verschlechterte Leistung, aber ich sehe nicht viel Auswahl, da ich viel Threading verwende.

+0

Es könnte Leuten helfen, Ihre Frage zu beantworten, wenn Sie einen Beispielcode geben, der die Art von Sache zeigt, die zu dem Problem führt. (Ich weiß * ich * habe nicht das Fachwissen, um dies zu beantworten; die STL ist nicht etwas, das ich gründlich studiert habe.) –

+0

Was meinen Sie mit "zugegriffen ... Objekte"? – LavaScornedOven

+0

Diese Frage wurde schon einmal gestellt (siehe http://stackoverflow.com/questions/4029448/thread-safety-for-stl-queue und http://stackoverflow.com/questions/1362110/is-the-c-stl- stdset-thread-safe), aber es gibt noch eine zentrale Antwort auf diese Frage. Da diese Version so gut wie jeder ist, um ** der ** zentrale Ort zu werden, um diese Frage in StackOverflow zu beantworten, verwenden Sie bitte eine große Überschrift, um den Namen Ihrer Implementierung einzufügen, und zitieren Sie und verlinken Sie auf die Originaldokumentation. –

Antwort

5

Die STL SGI

Die SGI STL ist die Großmutter von allen anderen STL-Implementierungen.

Siehe the SGI STL docs.

Die SGI Implementierung von STL ist threadsicher nur in dem Sinne, dass gleichzeitige Zugriffe auf unterschiedliche Behälter sicher sind, und gleichzeitige Lesezugriffe auf gemeinsam genutzten Behälter zu sicher sind. Wenn mehrere Threads auf einen einzelnen Container zugreifen und mindestens ein Thread potenziell schreiben kann, ist der Benutzer dafür verantwortlich, während der Containerzugriffe einen gegenseitigen Ausschluss zwischen den Threads sicherzustellen.

G ++

libstdc++ docs

Wir verwenden derzeit die SGI STL Definition der Thread-Sicherheit.

STLPort

STLPort docs

verweisen auf SGI-Website für detaillierte Dokument auf Thread-Sicherheit. Grund Punkte sind:

  • simultanen Lesezugriff auf den gleichen Behälter aus getrennten Gewinde ist sicher;
  • gleichzeitiger Zugriff auf verschiedene Container (nicht gemeinsam zwischen Threads) ist sicher;
  • Benutzer muss die Synchronisierung für alle Zugriffe bereitstellen, wenn ein Thread den freigegebenen Container ändern kann.
+0

Irgendwelche Informationen über die String-Referenzzählung? – doron

+0

Interessant, dass STLport-Dokumente sagen, dass "der gleichzeitige Zugriff auf unterschiedliche Container (die nicht zwischen Threads geteilt werden) sicher ist". Diese Funktion ist auf Android deaktiviert. – Ravi

2

Allgemeine Informationen über den C++ Standard-

Die aktuelle C++ Standard befasst sich nicht mit Concurrency Probleme überhaupt, so zumindest für jetzt gibt es keine Anforderung ist, die für alle Implementierungen gilt.

Eine sinnvolle Antwort kann nur wirklich auf eine bestimmte Implementierung zutreffen (in diesem Fall STLPort). STLPort ist im Grunde eine Version der ursprünglichen SGI-STL-Implementierung mit Verbesserungen der Portabilität, so dass Sie wahrscheinlich mit der documentation über Thread-Sicherheit in der ursprünglichen SGI-Version beginnen möchten.

+0

Die Dokumentation aus dem obigen Link erwähnt das Problem, das ich festgestellt: "Alloc.h verwendet drei verschiedene Sperrgrundelemente abhängig von der Umgebung. Darüber hinaus kann erzwungen werden Führen Sie keine Sperre durch, indem Sie _NOTHREADS definieren. " In der Android-Distribution wurde _NOTHREADS definiert. Wenn ich es nicht definiert habe, verschwanden die Probleme mit der Speicherbeschädigung. – Ravi

0

Sun WorkShop 5.0

This ist ein bisschen alt, aber sehr informativ. Die Quintessenz ist, dass STL nur Sperren für Zuweiser bereitstellt.

Strings sind jedoch referenzierte gezählte Objekte, aber jede Änderung ihrer Referenzzählung erfolgt atomar. Dies gilt jedoch nur, wenn Strings nach Wert übergeben werden. Zwei Threads, die denselben Verweis auf ein einzelnes String-Objekt haben, müssen ihre eigenen Sperren ausführen.

+0

Die aktuelle Linux-Implementierung enthält die Sperren. – doron

0

Wenn Sie z.B. std :: string oder ähnliche Objekte, und ändern Sie sie von verschiedenen Threads, teilen Sie das gleiche Objekt zwischen Threads. Um eine der Member-Funktionen aufzurufen, können Sie String Reentrant aufrufen, das bedeutet, dass kein anderer Thread unsere mem-Funktion beeinflussen kann und unsere Funktion keinen Einfluss auf andere Aufrufe in anderen Threads haben kann. Die Wahrheit ist genau das Gegenteil, da Sie das gleiche Objekt über diesen Zeiger teilen, der implizit beim Aufruf von Member-Objekten angegeben wird. Zur Veranschaulichung entspricht diesen Aufruf

std::string a; 
a.insert(...); 

ohne OOP-Syntax wäre:

std::string a; 
insert(&a, ...); 

Also, verletzen Sie implizit Anforderung, dass keine Ressource zwischen Funktionsaufrufen gemeinsam genutzt wird. Sie können mehr here sehen.

Hoffe, das hilft.

+0

Op teilt kein Objekt zwischen Threads. – Basilevs

1

Natürlich ist der Grund, warum es ohne Re-Enrancy ist für die Leistung: Geschwindigkeit, weniger Speicherverbrauch, weniger Ressourcen verwendet. Vermutlich liegt das daran, dass die meisten Client-Programme nicht multi-threaded sind.

Verwandte Themen