2014-03-31 6 views
11

ostream Operator << verwendet num_put::put() für die Formatierung von Zahlen. Ich versuche dem Code zu folgen. Ich verlinke auf OSX-Dateien, aber ähnliche Dateien erscheinen auf einigen anderen Systemen, die ich angeschaut habe. Es scheint mir, dass num_put::put() Anrufe num_put::do_put(), die
num_put::_M_insert_float() nennt, die calls __convert_from_v():Ist Ostream-Operator << in libstdC++ Thread-feindlich?

http://www.opensource.apple.com/source/libstdcxx/libstdcxx-60/include/c++/4.2.1/bits/c++locale.h 
http://www.opensource.apple.com/source/libstdcxx/libstdcxx-60/include/c++/4.2.1/bits/locale_facets.tcc 
http://www.opensource.apple.com/source/libstdcxx/libstdcxx-60/include/c++/4.2.1/bits/locale_facets.h 

__convert_from_v() prüfen die aktuellen globalen locale, und wenn es von „C“ ist anders dann nennt es setlocale() die globalen Locale zu setzen, um "C", verwendet dann vsnprintf(), um die Nummer zu formatieren, und ruft dann erneut setlocale() auf, um zum alten Gebietsschema zurückzukehren.

Da setlocale() alle Themen betrifft, so scheint es, dass ostream Operator << mit einem Gleitkommazahl Aufruf in einer Multi-Threaded-Anwendung nicht sicher ist, welche die globale Locale auf etwas anderes als „C“ gesetzt hat. Aber das wäre sehr seltsam, was vermisse ich dann? Vielen Dank!

+0

Es kann sein, dass die libstdC++ - Implementierung auf OS X dieses Problem hat. Es ist bekannt, dass es andere Probleme gibt, insbesondere wenn viele Gebietsschemamerkmale nicht vollständig implementiert sind (es verwendet nur das generische Gebietsschemamodell unter OS X). libstdC++ wird unter OS X nicht aktualisiert. Stattdessen wird libC++ die Standard-C++ - Bibliotheksimplementierung unter OS X sein und Sie sollten versuchen, diese zu verwenden. – bames53

+0

Ich habe meine Antwort aktualisiert, es ist kein Problem, da GCC auf allem außer Linux Gebietsschemas nicht unterstützt. – user657267

+0

@ JonathanWakely Das ist gut zu wissen. In welcher Version wurde die Unterstützung von xlocale hinzugefügt? (Die in dieser Frage verwendete Version ist 4.2.1, die alt genug ist, dass ich ziemlich sicher bin, dass sie xlocale nicht unterstützt hat.) – bames53

Antwort

4

Der neueste Entwurf (N3936) warnt ausdrücklich gegen diesen:

§ 18,10

6 Ein Aufruf die Funktion setlocale ein Datum Rennen mit anderen Anrufen an die setlocaleQ Funktion oder mit Anrufen können einführen Funktionen, die betreffen, sind vom aktuellen C-Gebietsschema betroffen. Die Implementierung soll sich so verhalten, als ob keine andere Bibliotheksfunktion als locale :: global() die setlocale-Funktion aufruft.

Neuere Versionen von GCC, den Anruf zu LC_NUMERIC statt LC_ALL begrenzen, und wenn Sie glibc verwenden> 2.2 die Umsetzung vermeidet das Problem ganz von uselocale Aufruf, die nur den aktuellen Thread modifiziert (nicht viel für Sie auf OSX Ich vermute…).

Edit: Ich hatte einen besseren Blick auf der Quelle

Obwohl Probleme möglicherweise mit dem allgemeinen locale-Modell auftreten könnten, wenn eine Funktion, die die C modifiziert von einem anderen Thread auf der C-locale abhängig, während __convert_from_v oder eine andere Funktion aufgerufen wird Gebietsschema, das einzige unterstützte Gebietsschema für das generische Gebietsschema-Modell ist "C" (das ist das Gebietsschema, das beim Start festgelegt wird). Dies ist also kein Problem, wenn dem generischen Modell keine Unterstützung für andere Gebietsschemas hinzugefügt wird.

Das einzige Mal, das dies ein Problem sein kann, ist, wenn gcc mit dem GNU Locale-Modell erstellt wird und glibc < = 2.2 ist, was unter OSX nicht passieren wird.