[C++11] thread_local: LLVM/Mavericks packts nicht. Alternativen?
-
Kurzgefasst: In einem Multi-Plattform Projekt für Windows und Mac stellte sich leider heraus, dass LLVM auch auf OS X Mavericks kein richtiges TLS unterstützt (oder ich bin zu dumm, um es zu konfigurieren). Sachen wie
static thread_local shared_ptr<foo> bar;gehen nicht und LLVM verabschiedet sich mit einem schlichten "unsupported".Ich wollte nun eine Map mit Locks bauen, welche thread::id als Keys und z.B. eben shared_ptrs als Value nimmt, aber dann werden die Destruktoren der Elemente nie/zu spät aufgerufen.
Gibt es eine (möglichst portable) Alternative zu thread_local, welche die C++-Semantik irgendwie unterstützt? Wenn nein, kann man Aktionen für das Ende eines Threads registrieren? Dann könnte ich das Cleanup selbst machen.
Vielen Dank für Ideen
-
ich kann mir nicht so viele anwendungen für thread local storage vorstellen. ist halt fast genauso doof wie globale variablen. ich würd davon die finger lassen, soweit es geht.
-
Das wundert mich, da LLVM angeblich eine 100% vollständige C++11 Unterstützung bietet.
Ich bin nicht sicher, was du genau machen möchtest, aber wäre es nicht möglich, den Threads den shared_ptr einfach als Funktionsparameter mitzugeben? Der sollte dann genauso lange leben wie der Thread.
-
krümelkacker schrieb:
ich kann mir nicht so viele anwendungen für thread local storage vorstellen. ist halt fast genauso doof wie globale variablen. ich würd davon die finger lassen, soweit es geht.
Wird hier ganz gut erklärt: https://stackoverflow.com/questions/11983875/what-does-the-thread-local-mean-in-c11
Schein aber tatsächlich eher dafür zu sein "Altlasten" threadsafe zu bekommen. Ansonsten würde man in diesen Fällen wohl besser einen Functor nehmen.
-
Die Boost.Thread Implementierung hat soweit ich weiss Thread-Locals die Destruktoren besitzen dürfen.
Wobei man auch da etwas aufpassen muss. Unter Windows laufen diese Destruktoren dann während der Loader-Lock gehalten wird. D.h. man kann in so einem Destruktor viele Dinge nicht "sicher" machen. Alles was dazu führen könnte dass andere DLLs geladen werden müssen kann zu einem Problem werden.
Threads Erzeugen geht auch nur bedingt - der Thread läuft erst an nachdem der Destruktor fertig abgearbeitet ist, d.h. der Destruktor darf nicht auf das Anlaufen des Threds warten.
Usw.
-
TNA schrieb:
Wäre es nicht möglich, den Threads den shared_ptr einfach als Funktionsparameter mitzugeben? Der sollte dann genauso lange leben wie der Thread.
Das Problem ist, dass das Objekt dazu genutzt werden sollte, um sonstige globale Variablen zu vermeiden (bzw. diese zu verstecken). Es handelt sich um eine Art Resolver welcher für jeden Thread ein anderer sein kann, aber auch von mehreren Threads gemeinsam genutzt werden könnte. Die Threads können allerdings nicht nur mit std::thread erzeugt werden (ist sogar eher die Ausnahme), sondern teilweise auch mit NSThread oder System.Threading.Thread (je nach System) - habe keine Kontrolle darüber, da es sich um eine Library handelt.
Wie gesagt, unter Windows funktioniert es

@hustbaer: boost ist eine gute Idee. Werde mir das mal anschauen.
danke
-
SFML hat einen Smart-Pointer sf::ThreadLocalPtr.