2011-05-21 18 views
8

En C, si mi aplicación finaliza inesperadamente, ¿puedo llamar a una función antes de que eso suceda? Estoy escribiendo una bandera en una base de datos (processRunning = 1) que impide que otras aplicaciones comiencen un proceso similar. Cuando la aplicación finaliza, no cambiará esa bandera.C: Hacer algo cuando el programa sale

Respuesta

6

mira en el atexit API de la biblioteca estándar de C.

+0

Spot on. Gracias. –

+3

Esto no es una solución. No lo protegerá de una terminación anormal. La función 'atexit' es en gran medida inútil en la práctica, y excepto en pequeños programas que nunca llegarán a ser grandes o se convertirán en bibliotecas, su uso probablemente debería considerarse perjudicial ya que necesariamente involucra variables globales/estado global. –

+2

Probablemente ambos ya sepan esto, pero cosas como interrupciones de red y fallas de energía pueden evitar que ese tipo de código se ejecute. Puede ser más sólido escribir marcas de tiempo en la base de datos cada 'n' minutos y dejar que la base de datos limpie las banderas abandonadas después de 'n + m' minutos sin marcas de tiempo. –

4

Si su aplicación termina normalmente, ejecutará funciones registradas a través de atexit. Esta es una función estándar, disponible en Windows, unix y en cualquier otra plataforma, y ​​también en C++.

Tenga en cuenta que "termina normalmente" significa a través de llamadas a exit() o volviendo de main(). Si su aplicación finaliza a través de abort() o _exit(), o si se mata sumariamente desde el exterior, es posible que no tenga la oportunidad de realizar ninguna limpieza. Puede haber un mejor enfoque, posiblemente configurando y borrando la bandera en un programa envoltorio que realiza la limpieza independientemente de cómo termine su programa, o prescindiendo de esta bandera por completo.

+0

Gracias por el consejo adicional, Gilles. Estaba pensando en algo. similar a tener una aplicación de verificación cada pocos segundos si los procesos asociados a un PID específico todavía se están ejecutando. –

+0

Una solución podría ser incursionar con señales de captura. (Supongo que no será aplicable en Windows.) –

+1

@Frank: Tenga en cuenta que la comprobación por PID no es infalible. El PID podría reutilizarse rápidamente por un proceso no relacionado. – Gilles

2

Existen mejores formas de evitar que la aplicación se ejecute dos veces. Una solución es usar mutexes con nombre que son de todo el sistema. Otra solución y quizás más simple es bloquear un archivo (abierto para escritura). Incluso cuando la aplicación bloquee los recursos, el SO los liberará y podrá volver a iniciar la aplicación, ya que el archivo o el mutex ya no estarán bloqueados.

5

En POSIX, la solución adecuada es proteger los datos con un mutex robusto en la memoria compartida. Si su proceso ha muerto con un mutex robusto retenido, otro programa que intente bloquear el mutex no se estancará, sino que devolverá EOWNERDEAD, y luego tendrá la oportunidad de limpiar el estado protegido por el mutex y llamar al pthread_mutex_consistent.

Edit: Si solo desea evitar que se ejecuten varias instancias del programa, seguramente hay formas mejores/más simples, como mantener un bloqueo en el archivo de la base de datos.

+0

+1 no lo sabía. Gracias, Frank –

Cuestiones relacionadas