Diese Antwort kann einen Zusatz von ildjarn gegeben, um die Antwort in Betracht gezogen werden. Wenn streng genommen vom C++ 14-Standard gesprochen wird, führt die Verwendung von Daten mit thread_local-Speicher von einem Signal-Handler zu undefiniertem Verhalten.
Auf bestimmten Plattformen ist eine solche Verwendung jedoch zulässig. Zum Beispiel implementieren die meisten POSIX-Systeme threadlokalen Speicher unter Verwendung eines speziellen Datensegments, das pro Thread zugewiesen wird (wie der Stapel). Ausführliche Erläuterungen finden Sie unter this document. In diesem Fall ist der Zugriff auf lokale Thread-Daten async-sicher, da es keine Sperren enthält.
Die vom Signalhandler gelesenen oder geschriebenen Daten sind jedoch möglicherweise immer noch inkonsistent, wenn nicht nur auf Atomics zugegriffen wird oder der Zugriff durch Verwendung von std::atomic_signal_fence
umzäunt wird. Der Grund dafür ist, dass der Compiler nun eine Idee hat, wenn ein Signal-Handler die Ausführung unterbrechen könnte und somit Lese- und Schreib-Befehle neu anordnen könnte. std::atomic_signal_fence
verbietet diese Neuordnung und Umordnung durch die CPU ist kein Problem, da die Ausführung innerhalb des gleichen Threads geschieht und die CPU nur Befehle neu anordnen darf, wenn das Ergebnis (innerhalb des Threads) gleich ist, als ob die Anweisungen in der Reihenfolge ausgeführt worden wären .
Zusätzlich zu std :: atomic_signal_fence ist die Verwendung von Variablen vom Typ std :: atomic sicher, solange sie frei von Sperren sind (wie durch std :: is_lock_free angezeigt).
Unter Linux (und ich glaube die meisten anderen POSIX-Plattformen) hängt die Frage, ob ein Signal an einen bestimmten Thread gesendet wird, davon ab, wie dieses Signal erzeugt wird und die genaue Art des Signals. Beispielsweise werden SIGSEGV
und SIGBUS
immer an den Thread gesendet, der den Fehler verursacht hat, der zu dem Signal geführt hat. In diesem Fall kann die Verwendung von lokalem Thread-Speicher eine bequeme Möglichkeit sein, um sich von solchen Fehlern zu erholen. Es gibt jedoch keine Möglichkeit, dies zu tun, während der Code für alle Plattformen, die den C++ - Standard unterstützen, portabel ist.
Signalhandler sind durch [\ [support.runtime \]/10] (http://eel.is/c++draft/support.runtime#10) eingeschränkt. –