Ist std::string thead-safe mit gcc 4.3?
Entwickle ich ein Multithread-Programm läuft auf Linux (kompiliert mit G++ 4.3) und wenn Sie suchen, um für ein bisschen Sie finden viele schreckliche Geschichten über std::string nicht thread-safe ist mit GCC. Dies ist vermutlich auf die Tatsache zurückzuführen, dass es intern verwendet copy-on-write, die verheerende Auswirkungen mit tools wie Helgrind.
Ich habe ein kleines Programm, das kopiert eine Zeichenfolge in eine andere Zeichenfolge und wenn Sie inspizieren die beiden Zeichenfolgen, die Sie beide teilen die gleichen internen _M_p Zeiger. Wenn ein string geändert wird, ändert sich der Zeiger, so dass das copy-on-write-stuff ist in Ordnung.
Was ich bin besorgt obwohl was passiert, wenn ich Teile einer Zeichenfolge zwischen zwei threads (zum Beispiel indem er als ein Objekt in einer threadsicher dataqueue zwischen zwei threads). Ich habe bereits versucht zu kompilieren, mit der '-pthread' option, aber das scheint nicht viel Unterschied. Also meine Frage:
- Gibt es eine Möglichkeit zu zwingen, std::string threadsicher? Ich würde nicht dagegen, wenn die copy-on-write-Verhalten deaktiviert wurde, dies zu erreichen.
- Wie haben andere Leute das Problem gelöst? Oder bin ich paranoid?
Ich kann nicht scheinen zu finden, eine definitive Antwort, so dass ich hoffe, Euch kann mir helfen..
Edit:
Wow, das ist eine ganze Menge von Antworten in so kurzer Zeit. Danke!!! Ich werde auf jeden Fall nutzen Jack ' s Lösung, wenn ich Sie deaktivieren möchten, KUH. Aber jetzt die wichtigste Frage: muss ich wirklich deaktivieren KUH? Oder ist die 'Buchführung' erfolgt für KUH-thread-safe? Ich bin momentan im libstdc++ - Quellen, aber das wird einige Zeit dauern, um herauszufinden,...
Edit 2
OK durchsuchten die libstdc++ - source-code und ich finde so etwas in libstd++-v3/include/bits/basic_string.h:
_CharT*
_M_refcopy() throw()
{
#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
if (__builtin_expect(this != &_S_empty_rep(), false))
#endif
__gnu_cxx::__atomic_add_dispatch(&this->_M_refcount, 1);
return _M_refdata();
} //XXX MT
Also es ist definitiv etwas, das es zu atomaren änderungen an der Referenz-Zähler...
Abschluss
Ich bin-Kennzeichnung sellibitze Kommentar als Antwort hier, weil ich denke, wir haben zu der Schlussfolgerung gelangt, dass dieser Bereich ist immer noch ungelöst, jetzt. Zur Umgehung der KUH Verhalten würde ich vorschlagen, Jack Lloyd ' s Antwort. Ich danke Ihnen allen für eine interessante Diskussion!
- +1 gute Frage! Leider, die Menschen nur Lesen "threadsicher" und denke "Nein!". Sie besser Lesen Sie die gesamte Frage! 🙂
- Da std::string ist eine Instanz der template std::basic_string es könnte möglich sein, für Sie zu werfen Sie einen Blick auf den source-code. Versuchen Sie, für jedes makro, das würde wiederum on/off thread-Sicherheit.
- Übrigens, copy-on-write ist langsam in multi-threaded-Umgebungen, Sie sollten nicht benutzen willst, nicht bereit.
- Siehe auch stackoverflow.com/questions/1661154/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Threads sind noch nicht Teil des standard. Aber ich glaube nicht, dass jeder Anbieter kann sich, ohne std::string, thread-sicher, heute. Hinweis: Es gibt verschiedene Definitionen von "thread-safe" und mir vielleicht von Ihnen unterscheiden. Es macht natürlich wenig Sinn, Sie zu schützen, die einen container wie std::vector für gleichzeitigen Zugriff standardmäßig, auch wenn Sie es nicht brauchen. Das würde gegen die "zahlen Sie nicht für Dinge, die Sie nicht verwenden" Geist von C++. Der Benutzer sollte immer verantwortlich für die Synchronisation wenn er/Sie teilen möchte-Objekte zwischen verschiedenen threads. Die Frage ist hier, ob eine Bibliothek-Komponente verwendet und teilt einige versteckte Daten-Strukturen können dazu führen, dass die Daten Rennen, auch wenn "Funktionen angewendet werden auf verschiedene Objekte" aus der Sicht des Benutzers.
Den C++0x draft (N2960) enthält der Abschnitt "data-race-Vermeidung", die im Grunde sagt, dass die Bibliothek-Komponenten können auf gemeinsame Daten zugreifen, die vom Benutzer ausgeblendet, wenn, und nur wenn es aktiv vermeidet mögliche Daten Rennen. Es klingt wie ein copy-on-write-Implementierung von std::basic_string sein muss als die sichere w.r.t. multi-threading als eine andere Implementierung, in denen interne Daten nie geteilt, zwischen den verschiedenen string-Instanzen.
Bin ich mir nicht 100% sicher, ob libstdc++ kümmert es schon. Ich denke, es ist. Um sicher zu sein, überprüfen Sie heraus die Dokumentation
Wenn Euch das nichts ausmacht Deaktivierung der copy-on-write, dies ist möglicherweise die beste Vorgehensweise. std::string KUH funktioniert nur, wenn es weiß, dass es das kopieren einer anderen std::string, so dass Sie kann dazu führen, dass immer reservieren eines neuen Blocks des Speichers und stellen eine tatsächliche Kopie. Zum Beispiel diesen code:
wird zeigen, dass die zweite Kopie (mit c_str) verhindert, dass die KUH. (Weil der std::string sieht nur einen nackten const char*, und hat keine Ahnung, Woher es kam oder was seine Lebensdauer sein mag, so hat Sie ein neues privates kopieren).
Diese Abschnitt der libstdc++ - Interna Staaten:
Die Referenz-Zählung sollte die Arbeit in einer multi-threaded Umgebung. (es sei denn, Ihr system nicht die notwendigen atomics)
Kein STL-container ist thread-sicher. Auf diese Weise verfügt die Bibliothek über einen Allgemeinen Zweck (beide verwendet werden, in single-threading-Modus oder ein multi-threading-Modus). In multithreading, müssen Sie die Synchronisations-Mechanismus.
Scheint es, dass dieses fest war vor einer Weile: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=5444 war geschlossen, als das gleiche Problem als http://gcc.gnu.org/bugzilla/show_bug.cgi?id=5432, das wurde behoben in 3.1).
Siehe auch http://gcc.gnu.org/bugzilla/show_bug.cgi?id=6227
Laut dieser bug Problem,
std::basic_string
's copy-on-write-Implementierung noch nicht vollständig thread-sicher.<ext/vstring.h>
ist eine Umsetzung ohne KUH und scheint zu tun, viel besser in einem nur-lese-Kontext.