8

En algún momento recuerdo haber leído que los hilos no se pueden crear de manera segura hasta la primera línea de main(), porque los compiladores insertan un código especial para hacer el trabajo de subprocesos que se ejecuta durante el tiempo de inicialización estático. Entonces, si tiene un objeto global que crea un hilo en la construcción, su programa puede bloquearse. Pero ahora no puedo encontrar el artículo original, y tengo curiosidad de cuán fuerte es esta restricción, ¿es estrictamente cierto según el estándar? ¿Es cierto en la mayoría de los compiladores? ¿Seguirá siendo verdad en C++ 0x? ¿Es posible que un compilador conforme a los estándares realice la inicialización estática en sí misma multiproceso? (por ejemplo, detectando que dos objetos globales no se tocan entre sí e inicializándolos en hilos separados para acelerar el inicio del programa)¿Se pueden crear hilos de manera segura durante la inicialización estática?

Editar: Para aclarar, intento al menos tener una idea de si las implementaciones realmente difieren significativamente a este respecto, o si es algo que es pseudo-estándar. Por ejemplo, técnicamente el estándar permite mezclar el diseño de los miembros que pertenecen a diferentes especificadores de acceso (público/protegido/etc.). Pero ningún compilador que conozca realmente hace esto.

+0

"es estrictamente cierto según el estándar" - el estándar C++ 03 no tiene nada que decir sobre el tema de los hilos. Los lugares para mirar en lo que respecta al comportamiento actual serían POSIX (que es, por supuesto, * a * estándar, simplemente no * el * estándar), MSDN, Boost u otros documentos específicos de implementación para el compilador, la plataforma y la API de threading. utilizar. –

Respuesta

6

Lo que está diciendo no está estrictamente en el idioma sino en la Biblioteca de tiempo de ejecución de C (CRT).
Para empezar, si crea un hilo usando una llamada nativa como CreateThread() en Windows, puede hacerlo en cualquier lugar que desee, ya que va directamente al sistema operativo sin la intervención del CRT.
La otra opción que usualmente tiene es usar _beginthread() que es parte del CRT. El uso de _beginthread() tiene algunas ventajas, como tener un errno seguro para subprocesos. Read more about this here. Si va a crear subprocesos usando _beginthread(), puede haber algunos problemas porque las inicializaciones necesarias para _beginthread() pueden no estar en su lugar.

Esto se refiere a un problema más general de lo que ocurre exactamente antes de main() y en qué orden. Básicamente, usted tiene la función de punto de entrada del programa que se ocupa de todo lo que debe suceder antes de main() con Visual Studio. De hecho, puede mirar este código que se encuentra en el CRT y descubrir qué está pasando exactamente allí. La forma más fácil de llegar a ese código es detener un punto de interrupción en su código y observar los marcos de pila antes de main()

+0

Gracias, esto me da una idea de cómo es la situación en Windows con MSVC. Todavía tengo curiosidad acerca de otras plataformas, y realmente no responde si es seguro en Windows o no (¿_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ –

+0

Ojalá supiera esto también. Los documentos no parecen mencionarlo. – shoosh

2

El problema subyacente es una restricción de Windows sobre lo que puede y no puede hacer en DllMain. En particular, no debes crear subprocesos en DllMain. La inicialización estática a menudo ocurre desde DllMain. Entonces, lógicamente se deduce que no puede crear hilos durante la inicialización estática.

+1

Pero tenga en cuenta: 'Durante el inicio del proceso y las rutinas de inicialización de DLL, se pueden crear nuevos subprocesos, pero no comienzan a ejecutarse hasta que se inicie la DLL para el proceso desde http://msdn.microsoft.com/en-us/library/ms682453% 28v = VS.85% 29.aspx –

+0

Punto justo, no había visto eso. Sin embargo, tenga en cuenta que el comentario se aplica específicamente a 'CreateThread',' _beginthreadex' no tiene esta excepción. – MSalters

0

Por lo que puedo decir al leer el borrador de C++ 0x/1x, comenzar un hilo antes de main() está bien, pero aún está sujeto a las trampas normales de la inicialización estática. Una implementación conforme deberá asegurarse de que el código para inicializar el subprocesamiento se ejecuta antes que cualquier constructor estático o de subprocesos.

Cuestiones relacionadas