go - definicion - meta title y meta descripcion
En marcha, ¿hay una manera de ejecutar código al finalizar el programa? (3)
En general, estoy de acuerdo con la respuesta de jnml. Sin embargo, si aún así desea hacerlo, puede usar la función defer en la función main()
, como esta: http://play.golang.org/p/aUdFXHtFOM .
Sé que puede definir funciones llamadas init
en cualquier paquete, y estas funciones se ejecutarán antes que main
. Uso esto para abrir mi archivo de registro y mi conexión de base de datos.
¿Hay alguna forma de definir el código que se ejecutará cuando finalice el programa, ya sea porque llega al final de la función main
o porque se interrumpió? La única forma en que puedo pensar es llamando manualmente una función de terminate
diferida en cada paquete usado por main, pero eso es bastante detallado y propenso a errores.
La funcionalidad de C atexit
fue considerada por los desarrolladores de Go y la idea de adoptarla fue rechazada.
De uno de los thread relacionados en golang-nuts:
Russ Cox :
Atexit puede tener sentido en programas de un solo hilo y de corta duración, pero soy escéptico de que tenga un lugar en un servidor multihilo de larga ejecución. He visto muchos programas de C ++ que se cuelgan en la salida porque ejecutan destructores globales que realmente no necesitan ejecutarse, y esos destructores están limpiando y liberando memoria que sería reclamada por el sistema operativo de todos modos, aunque solo sea el programa Podría llegar a la llamada del sistema de salida. Comparado con todo ese dolor, la necesidad de llamar a Flush cuando eres uno con un búfer parece completamente razonable y es necesario de todos modos para la ejecución correcta de programas de larga duración.
Incluso ignorando ese problema, atexit introduce aún más hilos de control, y ¿tienes que responder preguntas como si todas las otras goroutines se detuvieran antes de que se ejecuten los controladores atexit? Si no, ¿cómo evitan interferir? Si es así, ¿qué pasa si uno mantiene un bloqueo que el controlador necesita? Y así sucesivamente.
No estoy del todo inclinado a agregar Atexit.
El único mecanismo totalmente confiable es un programa envoltorio que invoca el programa real y realiza la limpieza cuando el programa real se completa. Eso es cierto en cualquier idioma, no solo en Go.
En mi opinión un tanto no formada, os.AtExit no es una gran idea. Es una instalación no estructurada que hace que ocurran cosas en el momento de salida del programa en un orden impredecible. Conduce a escenarios extraños como programas que tardan mucho tiempo en salir, una operación que debería ser muy rápida. También conduce a funciones extrañas como la función _exit de C, que más o menos significa funciones de salida-pero-no-ejecutar-atexit.
Dicho esto, creo que una función de salida especial correspondiente a la función init es una idea interesante. Tendría la estructura de la que carece os.AtExit (es decir, las funciones de salida se ejecutan en orden inverso a cuando se ejecutan las funciones de inicio).
Pero las funciones de salida no le ayudarán si su programa es destruido por el kernel, o se bloquea porque usted llama a algún código C que obtiene una violación de segmentación.
Si después de leer todo esto (y tal vez lo haya visto), aún desea atexit, eche un vistazo a https://github.com/tebeka/atexit :)