Esta es una publicación anterior, pero estaba buscando una buena forma de hacerlo y no me encontré con ninguna.
Tal vez esto ayude a alguien en una situación similar ..
que estoy haciendo esto en Windows, pero tal vez también es posible en OSX/Linux a través de los mutex pthread nombrados, aunque no sé la política de cómo se manejan dichos mutexes si se termina una aplicación, que es fundamental para esta técnica.
El problema de usar una sola bandera es que no funciona en la situación en la que puede haber múltiples instancias de la aplicación:
- App 1 ejecuta. Establece el indicador 'no se ha apagado correctamente'.
- Aplicación 2 carreras. Ve que no se ha cerrado porque la bandera está configurada y cree que hubo un bloqueo cuando no la había.
Esto es un poco difícil de conseguir alrededor y probablemente hay varias formas de hacer esto, pero este método parece funcionar bien hasta ahora (en Windows, por lo menos):
Crea un mutex llamado global con una GUID/UUID recién generado como nombre.
El GUID es diferente para cada instancia de la aplicación, por lo que cada uno tendrá un único mutex con nombre. El GUID se escribe en un archivo que contiene una lista de GUID. Si la aplicación se cierra correctamente, se elimina el GUID del archivo y se cierra el mutex. Si la aplicación falla o finaliza, el GUID no se elimina del archivo PERO el mutex es destruido por el SO sin que la aplicación tenga que hacerlo.
Al iniciar la aplicación, puede ejecutar los GUID en la lista y llamar a OpenMutex y mutexes que no existen (GetLastError devuelve ERROR_FILE_NOT_FOUND).Cualquier exclusión mutua no existente indica que se produjo un bloqueo/terminación. Todos los GUID que tienen esta propiedad se pueden eliminar de la lista en este momento.
Una cosa adicional que puede hacer es eliminar GUID incorrectos de la lista cuando se apaga correctamente. esto se pone alrededor de la siguiente situación:
- Aplicación 1 comienza
- App 2 comienza
- ! 1 accidentes
- App 2 está cerrado correctamente
- Aplicación 3 se ha iniciado.
Cuando se inicia la aplicación 3, no se debe publicar que hubo un bloqueo, porque el último apagado fue correcto.
También implementé un tipo de spinlock para obtener acceso al archivo que contiene los GUID que continuarán después de un período de tiempo de espera y no agregue el guid de la aplicación al archivo. En tales casos, probablemente sea mejor dejar que la aplicación se ejecute de todos modos y perder la detección de bloqueo, en lugar de no ejecutar la aplicación en absoluto.
Otras advertencias son aferrarse al bloqueo de archivos al consultar y actualizar el archivo para evitar condiciones de carrera. En Windows, esto evita el uso de stl filestreams, ya que tendrá que truncar el archivo después de leerlo mientras mantiene el acceso exclusivo al archivo.
Hmm? ¿Y dónde escribiría este archivo? ¿Estás seguro de que se envía la aplicación WillQuit o los métodos de notificación antes de que * se bloquee *? Y aunque lo hiciera, ¿alguno de estos métodos de QQue realmente tiene un parámetro que dice que la aplicación se está bloqueando o no se está bloqueando? – Enchilada
Oooh, creo que te entiendo. Quiere decir simplemente poner un SuccessfulQuit en los valores predeterminados del usuario, que siempre se establece en 1 al salir exitosamente, es 0 de manera predeterminada, y se establece en -1 una vez que la aplicación termina de iniciarse. Y luego, si en realidad es -1 cuando lo lanzo, significa que debí haber fallado. ¿Algo como eso? – Enchilada
Sí, y leer/escribir el archivo en una ubicación depende de usted. –