Qual è il modo migliore per impedire che un programma/demone Linux venga eseguito più volte in un dato momento?Come impedire a un programma Linux di essere eseguito più di una volta?
risposta
Il modo più comune è quello di creare un file PID: definire una posizione in cui il file andrà (dentro/var/run è comune). In caso di avvio riuscito, scriverai il tuo PID in questo file. Al momento di decidere se avviarsi, leggere il file e verificare che il processo di riferimento non esista (o se lo fa, che non è un'istanza del demone: su Linux, è possibile consultare /proc/$PID/exe
). All'arresto, è possibile rimuovere il file ma non è strettamente necessario.
Ci sono degli script per aiutarti a fare questo, potresti trovare utile start-stop-daemon
: può usare i file PID o anche solo verificare globalmente l'esistenza di un eseguibile. È stato progettato proprio per questo compito ed è stato scritto per aiutare le persone a farlo bene.
Se si ha accesso al codice (cioè sono scriverlo):
- creare un file temporaneo, bloccarlo, rimuovere una volta fatto,
return 1;
se file esiste, o, - processi lista,
return 1;
se il nome del processo è nella lista
Se non lo fai:
- creat e un wrapper di avvio per il programma che fa uno dei precedenti
Ok , sembra interessante. Ma cosa succede se il processo viene ucciso prima che possa rimuovere il file temporaneo? –
Questo è un problema, si. Potresti usare il secondo metodo per evitare questo problema, comunque. –
Oppure un normale file come 'application.pid' su cui ottenere un blocco esclusivo, che alla fine dell'applicazione sarebbe stato rilasciato. – mhitza
Non so quale sia il vostro esatto requisito ma ho avuto un requisito simile; in quel caso ho avviato il mio demone da uno script Shell (era una macchina HP-UX) e prima di avviare il demone ho controllato se un exec con lo stesso nome è già in esecuzione. Se è; quindi non iniziare uno nuovo.
In questo modo sono stato anche in grado di controllare il numero di istanze di un processo.
e come si controlla se "un exec con lo stesso nome è già in esecuzione"? – phunehehe
È possibile elencare i processi in esecuzione utilizzando il comando 'ps'. Almeno in HP-UX. – Vaibhav
Ho uno script che funziona così. È molto utile, ma è impossibile farlo in modo affidabile. Per esempio. se exec è uno script, quello che vedrai in esecuzione è l'interprete (sh, o perl o qualsiasi altra cosa) e il nome dello script è il primo argomento. Ma è anche possibile eseguire un programma con un nome falso, nel qual caso non si sa come identificarlo. Puoi anche guardare il filesystem/proc. Ma non c'è modo di renderlo affidabile al 100%. – reinierpost
Utilizzare boost interprocess library per creare un blocco di memoria che verrà creato dal processo. Se esiste già, significa che c'è un'altra istanza del processo. Uscita.
Il collegamento più preciso a quello che ti serve è 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
}
Funzionerà se il processo viene ucciso con -9 prima che possa liberare shared_memory_object? – rustyx
penso che questo schema dovrebbe funzionare (ed è anche resistente agli urti):
Presupposto: C'è un file PID per l'applicazione (in genere in/var/run /)
1. Tentare di aprire il file PID
2. Se non esiste, crearlo e scrivere il PID su di esso. Continuare con il resto del programma
3. Se esiste, leggere il PID
4. Se il PID è ancora in esecuzione e è un'istanza del programma, quindi uscire
5. Se il PID non esiste o viene utilizzato da un altro programma, rimuovere il file PID e andare al passaggio 2.
6. Al termine del programma, rimuovere il file PID.
Il ciclo del passaggio 5 garantisce che, se due istanze vengono avviate contemporaneamente, solo una verrà eseguita alla fine.
Non rimuoverei il file pid se non ha il tuo pid in quanto può introdurre una condizione di competizione. – MarkR
Avere un file pid e all'avvio fare un 'kill -0 <pid>'
. Dove è il valore letto dal file. Se la risposta è! = 0, il daemon non è vivo e potresti riavviarlo.
Un altro approccio sarebbe quello di collegarsi a una porta e gestire l'eccezione di bind al secondo tentativo di avviare il demone. Se la porta è in uso, esci altrimenti continua a eseguire il demone.
Il kill -0 ti dirà solo che il processo esiste, non che è il tuo demone. Ho visto un fastidioso bug dove (al momento dell'avvio, dove i numeri pid sono sequenziali) un altro processo prende lo stesso pid e ha causato un errore erroneo all'avvio di un daemon. – MarkR
Credo che la mia soluzione è la più semplice:
(non usarlo se la condizione di corsa è uno scenario possibile, ma in tutti gli altri casi si tratta di una soluzione semplice e soddisfacente)
#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. Posso aggiungere l'attributo onmouseover per essere eseguito una sola volta?
- 2. Fare un'applicazione .NET l'unico programma che può essere eseguito?
- 3. Flask: come impedire a JS di Google Analytics di essere eseguito in ambiente dev?
- 4. L'ob_start di PHP può essere chiamato più di una volta?
- 5. Come impedire che una modale venga disegnata più di una volta?
- 6. Come posso impedire agli utenti di votare più di una volta?
- 7. "L'oggetto può essere smaltito più di una volta" Errore
- 8. Come impedire a Xcode di ricostruire il progetto ogni volta
- 9. Come evitare più istanze di un programma?
- 10. Tra cui un modulo più di una volta
- 11. Discussione viene eseguito solo una volta
- 12. Come sostituire più di una volta?
- 13. Come impedire a un programma grafico Java di rubare lo stato quando si aggiorna la finestra?
- 14. Come impedire a RichTextBox Inline di essere eliminato in TextChanged?
- 15. Come impedire a ksh su Linux di sovrascrivere un varibale globale con una variabile locale?
- 16. Errore di commit SVN "Il commit può essere eseguito solo su un singolo repository alla volta."
- 17. JavaScript - eseguito una volta senza booleans
- 18. script di distribuzione post ssdt eseguito una volta
- 19. setInterval callback viene eseguito solo una volta
- 20. setTimeout viene eseguito solo una volta?
- 21. Gulp Watch eseguito una sola volta
- 22. Può essere eseguito come una singola query di aggiornamento?
- 23. JS setInterval eseguito solo una volta
- 24. Come posso impedire a windbg di essere il debugger interattivo?
- 25. Impedire a "Più" di riorganizzare le cose
- 26. Come eseguire Cronjobs più di una volta al minuto?
- 27. Limitazione del tempo di esecuzione di un programma in Linux
- 28. Come impedire a grep di stampare una nuova riga finale?
- 29. Joomla Menu-alias più di una volta
- 30. un programma per monitorare una directory su Linux
In genere è una buona idea usare 'flock' su un file pid per assicurarsi che il processo che usa il pid sia, di fatto, il tuo. – Hasturkun
Sì, metti un blocco esclusivo sul file pid e lascialo lì. Se il blocco fallisce, è in esecuzione un'altra istanza. – MarkR
Dipende dal fatto che si stia scrivendo il file PID utilizzando il processo daemon o meno: se si utilizza 'start-stop-daemon' o simile, non è possibile bloccare il file in questo modo. Inoltre, anche se riesci a ottenere il blocco, dovresti comunque controllare il PID contenuto nel file, quindi non sono sicuro che ti guadagni molto. –