¿Cuál es la mejor manera en la plataforma Linux para que el proceso (aplicación C++) compruebe que su instancia ya no se está ejecutando?Prevención de múltiples instancias de proceso en Linux
Respuesta
La forma estándar de hacer esto es crear un archivo pid en alguna parte, que generalmente contiene el pid de su programa.
No necesita poner el pid allí, simplemente podría ponerle un candado exclusivo. Si lo abre para leer/escribir y lo agrupa con LOCK_EX | LOCK_NB, fallará si el archivo ya está bloqueado. Esto es libre de condición de carrera y el bloqueo se liberará automáticamente si el programa falla.
Normalmente, querrá hacerlo por usuario, por lo que el directorio de inicio del usuario es un buen lugar para guardar el archivo.
Si es un daemon, en algún lugar como/var/run es mejor.
Puede usar archivos y bloqueos de archivos para lograr esto, pero tenga cuidado de que no sea perfecto y no copie el infame error de Firefox donde se niega a arrancar a veces incluso si no se está ejecutando.
La lógica básica de la misma es:
Invariant:
File xxxxx will exist if and only if the program is running, and the
contents of the file will contain the PID of that program.
On startup:
If file xxxxx exists:
If there is a process with the PID contained in the file:
Assume there is some instance of the program, and exit
Else:
Assume that the program terminated abnormally, and
overwrite file xxxx with the PID of this program
Else:
Create file xxxx, and save the current PID to that file.
On termination (typically registered via atexit):
Delete file xxxxx
Además de la lógica anterior, también debe utilizar un segundo archivo que se bloquea con el fin de sincronizar el acceso al archivo PID (esto es, actuar como una mutex para que sea seguro en términos de concurrencia a nivel de proceso).
Una alternativa relacionada a la solución de Michael es crear un directorio en una ubicación conocida (probablemente en/var/run o/tmp) y utilizar el éxito/fracaso de la llamada del sistema como mecanismo para garantizar la exclusión mutua. Este es el mismo truco de exclusión mutua que CVS ha utilizado durante años, ya que la creación de directorios es atómica en la mayoría (quizás todos) de los sistemas operativos básicos. Un archivo PID sigue siendo útil en el caso en que el proceso de creación de directorio + PID falle inesperadamente y no se pueda limpiar. Además, cuando verifique si el directorio + PID existente es válido, sugeriría que se verifique explícitamente el enlace simbólico /proc/<PID>/exe
para verificar que apunta a su ejecutable en lugar de solo suponer que el PID no se ha reciclado.
Puede usar POSIX named semaphore para hacerlo. Es mucho más seguro que usar un bloqueo de archivos.
¿Cómo lidia con un programa que se colgó sin limpiar el semáforo? –
desde la página man: los semáforos con nombre POSIX tienen persistencia del kernel: si no lo elimina sem_unlink(), existirá un semáforo hasta que se cierre el sistema. Crash definitivamente será un problema aquí. – jackhab
Para una aplicación de escritorio, probablemente sea más factible comprobar si se inicia una instancia para usuario actual, de modo que dos usuarios puedan tener sus propias instancias ejecutándose.
Puede usar algunas bibliotecas (libunique (GTK +) o QtSingleApplication (Qt)), o hágalo usted mismo. Además del archivo pid mencionado anteriormente, puede abrir un socket FIFO o dominio UNIX en algún lugar del directorio de inicio del usuario. De esta manera, podría comunicarse con la instancia en ejecución, por ej. elevar la ventana de la instancia en ejecución o indicar a la instancia en ejecución que abra un nuevo archivo/URI/lo que sea.
- 1. Múltiples instancias de singleton en bibliotecas compartidas en Linux
- 2. cuarzo: prevención de instancias simultáneas de un trabajo en jobs.xml
- 3. Múltiples instancias de Redis
- 4. Múltiples instancias de IntentService en Android
- 5. La prevención de varias instancias de mi solicitud
- 6. Proceso de fondo en Linux
- 7. Impedir instancias de formularios múltiples
- 8. Múltiples instancias de variables estáticas
- 9. Múltiples instancias de intención pendiente
- 10. ¿Múltiples instancias de iPhone Simulator?
- 11. Javascript str.search() instancias múltiples
- 12. Prevención de múltiples votos diarios en un concurso
- 13. Estadísticas del proceso de medición en Linux
- 14. Comprobar si el proceso se ejecuta en Windows/Linux
- 15. Aplicación ASP.NET instalador de MSI instancias múltiples
- 16. Iniciando múltiples instancias upstart automáticamente
- 17. apio con múltiples instancias de django
- 18. Múltiples instancias de una sola DLL MEF
- 19. Múltiples instancias en una página con Javascript
- 20. Mapa de memoria de proceso (Linux Windows)
- 21. Linux: detectar en tiempo de ejecución que un proceso tiene múltiples hilos
- 22. Varias instancias de w3wp.exe
- 23. Múltiples instancias de encabezado() + die() en línea de código único
- 24. Múltiples instancias de autocompletar de jQuery en una página
- 25. Proceso de reinicio en el cambio de archivos en Linux
- 26. Proceso JVM y Java Linux
- 27. Prevención de falta de memoria en Android
- 28. Prevención de mensajes bloqueados en Windows
- 29. Cambiar el nombre del proceso en Linux
- 30. ¿Cómo detener el proceso 'ininterrumpible' en Linux?
¿No sería más sencillo utilizar un socket en lugar de un archivo e intentar vincularlo a un puerto predefinido? Y, por cierto, ¿por qué no puedo usar el bloqueo de archivos sin toda la verificación pid? – jackhab
@Jack, puedes hacerlo sin verificación PID, pero luego corres el riesgo de asumir que el programa está abierto cuando se ha bloqueado y no ha podido limpiar el archivo (piensa en el problema de Firefox). Además, Rakis plantea un buen punto, que es que, en Linux, puede verificar que el PID pertenece a su programa utilizando los datos en '/ proc' ... hay formas programáticas de hacerlo de manera más genérica en las variantes de UNIX (como mínimo, podría invocar "ps" y analizar su salida, aunque creo que puede haber funciones que pueda invocar para obtener la información del proceso directamente). –
para verificar la existencia de un proceso, call kill (pid, 0). Esto tiene éxito cuando existe el proceso; de lo contrario, falla. ¡Tenga cuidado con el proceso que se ejecuta en una máquina diferente! – Arkadiy