c++11 thread_local Stichwort support in visual studio 11

So gibt es eine Liste der c++11-features von visual studio unterstützten.

thread_local Unterstützung gekennzeichnet ist, als Teil. Ich war nicht in der Lage zu finden, eine Erklärung, was genau die partielle Unterstützung bedeutet hier. Haben Sie nur alias __declspec(thread)?

Konnte ich nur die Verwendung von boost::thread_specific_ptr, aber dort scheint es einige Berichte, dass boost::thread_specific_ptr langsam ist. Kann oder kann nicht wahr sein.

Speziell möchte ich schnell TLS auf x86/x64 auf die neueste linux+gcc und windows+msvc. Schnell Bedeutung kein system Anrufe, bei denen das möglich ist (ich denke, dies ist möglich für die oberen Plattformen.)

  • Visual C++ 11 Developer Preview unterstützt nicht die thread_local Schlüsselwort.
  • Mein Verständnis ist, dass "teilweise" bedeutet hier, dass die Semantik unterstützt werden, aber nicht durch die standard-syntax-Schlüsselwort.
  • Entweder GNU, POSIX, Microsoft, SUN, IBM, und die C++ - std-Ausschuss sind alle Einrichtungen, für etwas, das nicht notwendig ist, gut gestaltete software oder dein Verständnis ist falsch. Aber ich würde gerne hören, ist Ihr argument.
  • Nee, TLS nützlich sein kann. Sie sind richtig in dem Sinne, dass TLS ist im wesentlichen eine weitere Globale, aber globals haben Ihre Verwendung.
  • Eloff: wenn TLS verwendet wird? In einem Fall ist errno, GetLastError - diese sind nur eine andere Art der Rückgabe von Fehlercodes. Es kann bequemer sein, als er es wieder direkt, aber ich bin absolut dagegen im Allgemeinen. Ich will nicht jede Bibliothek hinzufügen, ein Wort der Speicher in jedem meiner thread, der vielleicht nicht einmal die Bibliothek benutzen. Ein anderer Fall: Kontexte, wie die OpenGL-rendering-Kontext. Man kann argumentieren, dass es bequemer für das Kontextmenü einmal und dann davon ausgehen, dass es global, aber dann versuchen, das Rendern auf mehrere Kontexte von einem thread, oder entwerfen Sie einen OOP-wrapper für den Kontext, um zu sehen, warum es ist fehlerhaft.
  • Nichts davon hat zu tun mit TLS, das sind nur Argumente gegen die globals im Allgemeinen. Das ist in Ordnung, aber das ist nicht der Punkt hier. Gute Einsatzmöglichkeiten für globals und dann argumentieren Sie, dass TLS wird nie zu verbessern, und ist daher unnötig, in ein gutes Programm.
  • Ich hatte noch nie gesehen, gut verwendet globals. Gut, mit Ausnahme der Konstanten Daten, aber Konstante Daten müssen nicht TLS.
  • std::cout? Speicher-manager? OS?
  • Ich bin nicht einverstanden, auf std::cout. Vorausgesetzt, du meinst, dass der Speicher-manager ist "der Haufen", dann wieder: Sie müssen möglicherweise mehr als ein heap. Denken, warum STL mag allocators. 'OS' ist 'Konstante Daten' aus der Sicht des Programms, d.h. das OS nicht ändern, während Ihr Programm läuft.
  • Ich meinte bei der Umsetzung des OS. Aber in dem Fall der Speicher-Manager, der mehr als eine hat nichts zu tun mit der globalen oder nicht. Sie können mehrere Globale Haufen. Wie würden Sie implementieren std::cout?
  • OK, was physikalisch global global (z.B. hardware-Register und physischen RAM), aber Sie sind irrelevant für TLS. std::cout hat die Formatierung Staat, so es ist ein veränderliches Objekt. Ich würde lieber etwas wie std::ostream local_cout(standard_output); wo standard_output ändert sich nicht während der Prozessausführung.
  • globals haben Ihren nutzen. So kommt die TLS. Zum Beispiel, was, wenn Sie wollen, um Zufallszahlen zu generieren. Mit lokalen RNGs ist teuer, und auch eine möglicherweise schlechte Idee, je nach Saatgut. Macht es Sinn, eine Globale RNG. Aber es ist nicht thread-safe. Geben Sie TLS, dann hast du ein RNG-pro-thread. Das gleiche gilt, wenn Sie möchten, eine zusammengefasste Zuweisung für eine bestimmte Art von Objekt, Sie würde nicht machen es zu einem lokalen, weil Sie offensichtlich wollen, es zu teilen. Man konnte es thread-sicher ist, indem Sie einen pool pro thread (wie lange, wie Sie freie Objekte auf dem gleichen thread, ordnen Sie Sie auf)
  • Interessante Idee, ich mag es. 🙂 Das heißt, es gibt immer noch einen globalen Aspekt, und manchmal sogar globalen Dinge sind einfacher. Betrachten Sie eine log-Datei, zum Beispiel.
  • Der Wert von thread local storage ist so, dass die Dinge, die sonst global für das ganze Programm gemacht werden kann, weniger global. Zum Beispiel errno verwendet, um eine Globale und das bedeutete, dass Multithread-Programme nicht tun konnte, überprüft es auf Fehler, signalisiert mit errno zuverlässig. TLS > globals. Globale Variablen sollte man wirklich thread-lokalen und Sie sollten hinzufügen, ein spezielles Schlüsselwort, um das Programm Globale Variablen.
  • TLS kann wichtig sein in ein paar Fällen. Ich benutze es in meiner Bibliothek, da brauche ich einige Informationen, die beibehalten werden über die Bibliothek Anrufe auf einer pro-thread-basis, und da es eine Bibliothek ist, weiß ich nicht kontrollieren, die thread-stack, und kann nicht sehr gut Mandat, die der Anrufer sollte einige Besondere Objekt auf Ihrem Stapel. Ich weiß nicht bestreiten, dass TLS ist in der Regel etwas am besten vermieden werden, aber es ist für einen Grund. Oder um es anders zu sagen, gut gestaltete Programme werden vielleicht nicht brauchen, TLS, aber gut gestaltet Bibliotheken manchmal tun.
  • Ich sehe nicht, warum können Sie nicht das Mandat der Anrufer einen Kontext erstellen, der an Ihre Bibliothek. I. e. YourLibContext lib; lib.JumpFromTower();. Dies gibt Ihnen auch mehr Flexibilität und eine weniger Dereferenzierung pro Zugriff im Vergleich zu TLS. Ellof: was? Wie lokale RNGs sind teurer? RNGs sind ein gutes Beispiel, wenn Sie nicht wollen, weder globals noch TLS.
  • denn das würde es schwieriger machen, zu bedienen, fehleranfällig und schwieriger zu nachrüsten in bestehenden code. Ich habe Versuch mit diesem Konzept, aber es würde sich schon ein Schmerz zu verwenden 🙂
  • Es ist sicherlich Ausführlicher und kann somit Schmerzen verursachen, in einfachen Fällen. Aber es ist kein-Weg-mehr-Fehler-anfällig. Ich würde es zusammenzufassen als: "lassen Sie die Anrufer entscheiden, wo die Vergabe der Kontext ist, weil er es besser weiß" versus "Zuweisung der Kontext automatisch, so dass kein Raum für Anpassung und die Kraft die Hälfte der threads für was zu bezahlen was Sie nicht nutzen".
  • da in meinem Fall der Kontext ist absolut eine Implementierung detail, und es ist ziemlich wichtig, dass Sie genau einen Kontext pro-thread-Zugriff auf meine Bibliothek, ich bin nicht einverstanden. Mit zwei Kontexte im selben thread würde brechen die Semantik der Bibliothek. Ich dachte, dass das durch ganz gezielt. 😉
  • Die Bibliothek ist zu handhaben, die Synchronisation zwischen threads. Stell dir vor, Sie mussten vergehen, um den gleichen Kontext überall um sperren oder Mutexe. Machen diesem Kontext zugänglich über Rückrufe wäre der totale Schmerz. Und wenn du jemals mehr als einen Kontext, in einen einzigen thread, das ist ein Fehler, und die Synchronisation nicht so Verhalten, wie Sie erwarten würden. Ich würde gerne vermeiden alle Formen von globals, aber in meinem Szenario, es ist wirklich das einzige Konzept, das funktioniert
  • Nein, einige RNGs haben viel Platz overhead, klar, dass ist blöd reservieren und Samen, wenn Sie nur planen, ein solches zu generieren Zahl innerhalb einer Funktion. Die Zuteilung von RNG höher oben auf dem Aufruf-stack und übergeben Sie es durch jede Funktion ist ein schlechtes design IMHO. Aber das eigentliche problem mit lokalen RNGs ist, dass müssen Sie die Samen sorgfältig. Erstellen Sie innerhalb der aktuellen Funktion, seed mit der aktuellen Zeit (wie typisch), generieren Sie ein paar zahlen und zurückgeben. Rufen Sie die Funktion im inneren einer engen Schleife, und Sie erhalten den genau gleichen Samen (und zahlen) für einen großen run der Anrufe!
  • OK, in Ihrem Fall, dass Sie in der Tat brauchen eine Instanz pro thread durch die definition des Problems. Es ist der gleiche Grund, die Sie haben, z.B. ein stack pro thread. Dies sind Probleme, die direkt an das instruction-pointer. Ich spreche über Dinge, die es gibt keinen Grund, sich zu binden, Ihr Leben zum thread, aber Menschen immer noch denken, es ist 'schön zu tun'. E. g. Zufallszahlen-Generatoren. Keine Eloff. Ihr argument ist immer noch ungültig. Ich habe nicht gesagt, Sie haben nicht ein overhead. Weder sagte ich, schaffen Sie jedes mal, wenn Sie wollen, ziehen eine Nummer. Noch übergeben Sie es als einen expliziten parameter.
  • Sie müssen nur analysieren Sie Ihr design sorgfältig. Entscheiden, was ist die Lebensdauer der RNG, die Sie brauchen, und binden Sie es auf das Objekt, sagte der Lebensdauer. Schreiben Sie ein Spiel? Kein problem, die RNG wird ein Mitglied der Spiel-Status und bestanden überall indirekt über den Zeiger auf das Spiel. Es ist ein Monte-Carlo-simulation läuft in mehreren threads parallel? Kein problem, initialisieren einen Zufallszahlengenerator in das Objekt, welches die simulation.
  • Vorteile: 1) keine redundanten Kopien erstellt threads, die nicht nutzen es. 2) Sie sind berechtigt, zwei Instanzen der simulation in einem thread (alternierend, falls unterstützt) und das Ergebnis nicht davon abhängen, die Reihenfolge der Wechsel. 3) können Sie serialisieren der simulation und fortsetzen, wo Sie aufgehört haben-sogar auf einem anderen Rechner mit einer anderen Anzahl von threads. 4) Sie können unit-testen Sie Ihren code. Nachteile: natürlich, wenn Ihr Fall ist eine einfache Hausaufgabe zum drucken einer Liste von zufälligen Wörtern, dann dieses design ist nicht für Sie, und auch das gute alte rand() zu Ihren Bedürfnissen passt nur finden.

InformationsquelleAutor Eloff | 2012-01-07
Schreibe einen Kommentar