Können Threads während der statischen Initialisierung sicher erstellt werden?

8

An einem gewissen Punkt erinnere ich mich daran, dass Threads erst in der ersten Zeile von main () sicher erstellt werden können, weil Compiler speziellen Code einfügen, um das Threading während der statischen Initialisierungszeit auszuführen. Wenn Sie also ein globales Objekt haben, das bei der Konstruktion einen Thread erstellt, stürzt Ihr Programm möglicherweise ab. Aber jetzt kann ich den Originalartikel nicht finden, und ich bin gespannt, wie stark eine Einschränkung ist - ist das streng normgemäß? Stimmt das bei den meisten Compilern? Bleibt es in C ++ 0x wahr? Ist es für einen standardkonformen Compiler möglich, statische Initialisierung selbst multithread zu machen? (z. B. Erkennen, dass zwei globale Objekte einander nicht berühren und sie in separaten Threads initialisieren, um den Programmstart zu beschleunigen)

Edit: Um zu verdeutlichen, versuche ich zumindest ein Gefühl dafür zu bekommen, ob sich Implementierungen in dieser Hinsicht wirklich signifikant unterscheiden oder ob es sich um Pseudo-Standard handelt. Zum Beispiel erlaubt der Standard technisch das Mischen von Layouts von Mitgliedern, die zu verschiedenen Zugriffsspezifizierern gehören (öffentlich / geschützt / etc.). Aber kein Compiler, den ich kenne, tut das tatsächlich.

    
Joseph Garvin 18.09.2009, 15:06
quelle

3 Antworten

6

Worüber Sie sprechen, ist nicht streng in der Sprache, sondern in der C Run Time Library (CRT).
Für den Anfang, wenn Sie einen Thread mit einem systemeigenen Aufruf wie CreateThread() für Windows erstellen, dann können Sie es tun, wo Sie möchten, weil es direkt auf das Betriebssystem ohne Eingriff des CRT geht Die andere Option, die Sie normalerweise haben, ist _beginthread() zu verwenden, das Teil des CRT ist. Es gibt einige Vorteile bei der Verwendung von _beginthread() , wie z. B. ein thread-sicheres errno. Lesen Sie mehr dazu hier . Wenn Sie Threads mit _beginthread() erstellen, könnte es einige Probleme geben, da die für _beginthread() erforderlichen Initialisierungen möglicherweise nicht vorhanden sind.

Dies berührt eine allgemeinere Frage, was genau vor main() und in welcher Reihenfolge passiert. Im Grunde haben Sie die Einstiegspunktfunktion des Programms, die sich um alles kümmert, was passieren muss, bevor main() mit Visual Studio Sie tatsächlich dieses Stück Code betrachten können, das in der CRT ist und selbst herausfinden, was genau dort vor sich geht. Der einfachste Weg, zu diesem Code zu gelangen, besteht darin, einen Haltepunkt in Ihrem Code zu stoppen und die Stack-Frames vor main()

zu betrachten     
shoosh 18.09.2009 15:23
quelle
2

Das zugrunde liegende Problem ist eine Windows-Einschränkung, was Sie in DllMain tun können und was nicht. Insbesondere sollten Sie keine Threads in DllMain erstellen. Die statische Initialisierung geschieht häufig von DllMain. Dann folgt logisch, dass Sie während der statischen Initialisierung keine Threads erstellen können.

    
MSalters 21.09.2009 11:36
quelle
0

Soweit ich aus dem Lesen des C ++ 0x / 1x-Entwurfs ersehen kann, ist das Starten eines Threads vor main() in Ordnung, unterliegt aber den normalen Fallstricken der statischen Initialisierung. Eine konforme Implementierung muss sicherstellen, dass der Code zum Initialisieren von Threads ausgeführt wird, bevor statische oder Threadkonstruktoren ausgeführt werden.

    
coppro 22.09.2009 20:50
quelle