¿Cuál es la mejor manera de evitar que un programa/daemon de Linux se ejecute más de una vez en un momento determinado?¿Cómo evitar que un programa Linux se ejecute más de una vez?
Respuesta
La forma más común es la creación de un archivo PID: definir una ubicación donde el archivo se va (dentro/var/run es común). En el inicio exitoso, escribirá su PID en este archivo. Cuando decida si iniciar, lea el archivo y verifique para asegurarse de que el proceso al que se hace referencia no existe (o si lo hace, que no es una instancia de su daemon: en Linux, puede mirar /proc/$PID/exe
). Al apagarlo, puede eliminar el archivo pero no es estrictamente necesario.
Hay scripts para ayudarlo a hacer esto, puede encontrar que start-stop-daemon
es útil: puede usar archivos PID o incluso simplemente verificar globalmente la existencia de un ejecutable. Está diseñado precisamente para esta tarea y fue escrito para ayudar a las personas a hacerlo bien.
Si usted tiene acceso al código (es decir, está escribiendo):
- crear un archivo temporal, bloquearla, quite cuando se hace,
return 1;
si existe el archivo, o, - procesos de la lista,
return 1;
si el nombre del proceso está en la lista
Si no lo hace:
- creat e un contenedor de iniciador para el programa que hace uno de los anteriores
Ok , eso suena interesante. Pero, ¿qué pasa si el proceso se cancela antes de que pueda eliminar el archivo temporal? –
Eso es un problema, sí. Sin embargo, podría usar el segundo método para evitar este problema. –
O tenga un archivo normal como 'application.pid' para obtener un bloqueo exclusivo, que al final de la aplicación se liberaría. – mhitza
No sé cuál es su requisito exacto, pero tenía un requisito similar; en ese caso, inicié mi daemon a partir de un script de Shell (era un equipo HP-UX) y antes de iniciar el daemon comprobé si un ejecutivo con el mismo nombre ya se está ejecutando. Si esto es; entonces no comiences uno nuevo.
De esta manera, también pude controlar el número de instancias de un proceso.
y cómo se verifica si "un ejecutivo con el mismo nombre ya se está ejecutando"? – phunehehe
Puede enumerar los procesos que se ejecutan utilizando el comando 'ps'. Al menos en HP-UX. – Vaibhav
Tengo un script que funciona así. Es muy útil, pero es imposible hacer esto de manera confiable. P.ej. si el ejecutor es un script, lo que verá ejecutar es el intérprete (sh, o perl, o lo que sea) y el nombre del guión es el primer argumento. Pero también es posible ejecutar un programa con un nombre falso, en cuyo caso no sabrá cómo identificarlo. También puede ver el sistema de archivos/proc. Pero no hay forma de que esto sea 100% confiable. – reinierpost
Utilice boost interprocess library para crear un bloque de memoria que será creado por el proceso. Si ya existe, significa que hay otra instancia del proceso. Salida.
El enlace más preciso a lo que necesita sería this one.
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/scoped_ptr.hpp>
int main()
{
using boost::interprocess;
boost::scoped_ptr<shared_memory_object> createSharedMemoryOrDie;
try
{
createSharedMemoryOrDie.reset(
new shared_memory_object(create_only, "shared_memory", read_write));
} catch(...)
{
// executable is already running
return 1;
}
// do your thing here
}
Funcionará si el proceso se cancela con -9 antes de que pueda liberar shared_memory_object? – rustyx
creo que este esquema debería funcionar (y también es robusto frente a los choques):
Condición previa: Hay un archivo PID para su aplicación (normalmente en/var/run /)
1. Trate de abrir el archivo PID
2. Si no existe, créelo y escriba su PID en él. Continuar con el resto del programa
3. Si existe, leer el PID
4. Si el PID sigue en funcionamiento y es una instancia de su programa, a continuación, salga
5. Si no existe el PID o es utilizado por otro programa, elimine el archivo PID y vaya al paso 2.
6. Al finalizar el programa, elimine el archivo PID.
El ciclo en el paso 5 asegura que, si se inician dos instancias al mismo tiempo, solo una se ejecutará al final.
No eliminaría el archivo pid si no tiene su pid, ya que eso puede introducir una condición de carrera. – MarkR
Tener un archivo pid y en el inicio hacer un 'kill -0 <pid>'
. ¿Dónde se lee el valor del archivo? Si la respuesta es! = 0, entonces el daemon no está activo y puede reiniciarlo
Otro enfoque sería enlazar a un puerto y manejar la excepción de vinculación en el segundo intento de iniciar el daemon. Si el puerto está en uso, salga; de lo contrario, continúe ejecutando el daemon.
El kill -0 solo le dirá que el proceso existe, no que sea su daemon. He visto un error molesto en el que (en el momento del arranque, donde los números de pid son secuenciales), otro proceso toma el mismo pid y hace que un daemon falle al iniciarse. – MarkR
Creo que mi solución es la más sencilla:
(no lo use si la condición de carreras es un escenario posible, pero en cualquier otro caso se trata de una solución sencilla y satisfactoria)
#include <sys/types.h>
#include <unistd.h>
#include <sstream>
void main()
{
// get this process pid
pid_t pid = getpid();
// compose a bash command that:
// check if another process with the same name as yours
// but with different pid is running
std::stringstream command;
command << "ps -eo pid,comm | grep <process name> | grep -v " << pid;
int isRuning = system(command.str().c_str());
if (isRuning == 0) {
cout << "Another process already running. exiting." << endl;
return 1;
}
return 0;
}
- 1. evitar que una aplicación C# ejecute más de una instancia
- 2. ¿Cómo hacer que un bookmarklet se ejecute solo una vez?
- 3. cómo evitar que Sinatra se ejecute?
- 4. ¿Cómo configurar una tarea CRON para que se ejecute solo una vez por conjunto de instancias?
- 5. Crear una nueva tarea que ejecute un programa
- 6. ¿Cómo puedo hacer que un programa concurrente ya escrito se ejecute en una matriz de GPU?
- 7. ¿Cómo asegurar que la lógica del método se ejecute solo una vez por combinación de argumentos?
- 8. Evitar que se ejecute la tarea en segundo plano dispatch_after()
- 9. Quiere que procmail ejecute un script de python personalizado, cada vez que aparece un nuevo correo
- 10. ¿Es posible que un programa de subproceso único se ejecute simultáneamente en más de un núcleo de CPU?
- 11. ¿Puedo modificar un entorno Win7 para permitir que un programa .Net se ejecute siempre como administrador?
- 12. Linux: escriba un programa en C que 'controla' un shell
- 13. ¿Permitir -msse, -msse2 y -mfpmath = sse siempre hace que mi programa se ejecute más rápido?
- 14. ¿Cómo puedo evitar que los usuarios voten más de una vez en 1 hora?
- 15. ¿Cómo puedo evitar que los usuarios voten más de una vez?
- 16. Android: cree un servicio que se ejecute una vez al día
- 17. ¿Es posible hacer que un método se ejecute solo una vez?
- 18. Limitar el tiempo que un programa se ejecuta en Linux
- 19. Django y apio: ¿Cómo programo que un trabajo se ejecute solo una vez usando apio (similar al comando "a" en linux)?
- 20. 'VisualTree' se establece más de una vez
- 21. ¿Cargar una DLL más de una vez?
- 22. Haciendo que Mercurial se ejecute en Windows
- 23. ¿Cómo se permite ejecutar solo una instancia de un programa Java a la vez?
- 24. ¿Cómo me aseguro de que solo una de una determinada categoría de trabajo se ejecute a la vez en Hudson?
- 25. ¿Cómo evitar que Pharo ejecute un # startUp-Method de una clase?
- 26. Desarrollo iOS: ¿Cómo puedo evitar que un iPad ejecute una aplicación universal en el modo iPad?
- 27. ¿Los comentarios hacen que el código se ejecute más lento?
- 28. Pepino: antes de que el gancho se ejecute solo una vez para todos los escenarios
- 29. cómo hacer que jenkins ejecute un script de python que ejecute una compilación?
- 30. "objeto se puede disponer de más de una vez" error
Por lo general, es una buena idea usar 'flock' en un archivo pid para garantizar que el proceso que utiliza el pid sea, de hecho, tuyo. – Hasturkun
Sí, ponga un candado exclusivo en el archivo pid y déjelo allí. Si el bloqueo falla, se está ejecutando otra instancia. – MarkR
Eso depende de si está escribiendo el archivo PID usando el proceso del daemon o no: si está usando 'start-stop-daemon' o similar, no puede bloquear el archivo de esa manera. Además, incluso si logras obtener el bloqueo, debes verificar el PID que se encuentra dentro del archivo, así que no estoy seguro de que te haga ganar mucho. –