Qual è il modo migliore sulla piattaforma Linux per il processo (applicazione C++) per verificare che l'istanza non sia già in esecuzione?Prevenzione di più istanze di processo su Linux
risposta
Il modo standard per eseguire questa operazione è creare un file di pid da qualche parte, in genere contenente il pid del programma.
Non è necessario inserire il pid, è sufficiente inserire un blocco esclusivo. Se lo apri per lettura/scrittura e lo afferro con LOCK_EX | LOCK_NB, fallirà se il file è già bloccato. Questo è privo di condizioni di gara, e il blocco verrà rilasciato automaticamente se il programma si blocca.
Normalmente si vorrebbe farlo per utente, quindi la directory home dell'utente è un buon posto dove mettere il file.
Se è un demone, qualcosa come/var/run è migliore.
È possibile utilizzare file e blocchi di file per eseguire questa operazione, ma attenzione non è perfetto e non copiare il famigerato bug di Firefox in cui si rifiuta di avviarsi a volte anche se non è già in esecuzione.
La logica di base di esso è:
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
Oltre alla logica di cui sopra, si dovrebbe anche usare un secondo file che si blocca per sincronizzare l'accesso al file PID (cioè di agire come un mutex per renderlo sicuro in termini di concorrenza a livello di processo).
Un'alternativa correlata alla soluzione di Michael è creare una directory in una posizione nota (probabilmente in/var/run o/tmp) e utilizzare il successo/fallimento della chiamata di sistema come meccanismo per garantire l'esclusione reciproca. Questo è lo stesso trucco di mutua esclusione che CVS ha utilizzato per anni poiché la creazione di directory è atomica sulla maggior parte (forse tutti) dei sistemi operativi di base. Un file PID è ancora utile nel caso in cui la directory + processo di creazione PID muoia in modo imprevisto e non riesca a ripulire. Inoltre, quando si verifica se la directory esistente + PID è valida, suggerisco di verificare esplicitamente il collegamento simbolico /proc/<PID>/exe
per verificare che punti al file eseguibile piuttosto che assumere che il PID non sia stato riciclato.
Per eseguire questa operazione è possibile utilizzare POSIX named semaphore. È molto più sicuro dell'utilizzo di un blocco file.
In che modo si tratta di un programma che si è arrestato in modo anomalo senza ripulire il semaforo? –
dalla pagina man: i semafori con nome POSIX hanno la persistenza del kernel: se non viene rimosso da sem_unlink(), un semaforo esisterà fino a quando il sistema non verrà spento. Crash sarà sicuramente un problema qui. – jackhab
Per un'applicazione desktop, è probabilmente più possibile verificare se un'istanza viene avviata per utente corrente, in modo che due utenti possano avere le proprie istanze in esecuzione.
È possibile utilizzare una delle due librerie (libunique (GTK +) o QtSingleApplication (Qt)) oppure eseguire da soli. Oltre al file pid menzionato in precedenza, è possibile aprire un socket di dominio FIFO o UNIX da qualche parte nella home directory dell'utente. In questo modo, potresti comunicare con l'istanza in esecuzione, ad es. alzare la finestra dell'istanza in esecuzione o indicare all'istanza in esecuzione di aprire il nuovo file/URI/qualunque.
- 1. Prevenzione di più istanze di un'applicazione GTK
- 2. htop e top che mostrano più istanze di processo?
- 3. Stati di processo Linux
- 4. Distribuire su più istanze di Heroku
- 5. Più istanze di assegni
- 6. Come evitare più istanze di un programma?
- 7. Scrittura sull'esecuzione del processo 'immagine su Linux
- 8. Autorizzazioni processo Web su Yii/Linux
- 9. Restrizione dell'applicazione WinForm a un processo con più istanze
- 10. Scrapy - Come avviare più istanze dello stesso processo spider?
- 11. installazione di guardiani su più istanze di AWS EC2
- 12. Manutenzione di JNDI su più istanze di Tomcat
- 13. impostazione affinità cpu di un processo dall'inizio su linux
- 14. Il processo di multiprocesso termina con esito negativo su Linux
- 15. Più istanze di iPhone Simulator?
- 16. Limita più istanze di un'applicazione
- 17. Android - Prevenzione di WebView ricarica su Rotate
- 18. L'impostazione Cortesia processo (priorità) non ha alcun effetto su Linux
- 19. Impossibile creare più istanze di PowerPoint
- 20. Come calcolare e utilizzare la memoria di più istanze di un singolo processo utilizzando PowerShell?
- 21. più istanze di django su un singolo dominio
- 22. istanze di più negozi di flusso
- 23. Creazione di più istanze di un modulo
- 24. Utilizzo di più istanze di MemoryCache
- 25. Dump core Linux senza processo di omissione
- 26. Codice sorgente del processo init di linux
- 27. Mappa memoria di processo (Linux Windows)
- 28. Istanze multiple di w3wp.exe
- 29. Distribuzione di più istanze di un'applicazione Rails - stesso codice, più
- 30. per il processo linux
Non sarebbe più semplice utilizzare un socket anziché un file e provare a collegarsi a una porta predefinita? E, a proposito, perché non posso usare il blocco dei file senza la verifica del pid? – jackhab
@Jack, puoi farlo senza la verifica PID, ma poi corri il rischio di presumere che il programma sia aperto quando si è arrestato in modo anomalo e non è riuscito a ripulire il file (si pensi al problema di Firefox). Inoltre, Rakis porta un buon punto, che è che, su Linux, puoi verificare che il PID appartenga al tuo programma usando i dati in '/ proc' ... ci sono modi programmatici per farlo in modo più generico attraverso le varianti UNIX (come minimo potreste invocare "ps" e analizzare il suo output, anche se credo che ci possano essere funzioni che potete invocare per ottenere direttamente le informazioni sul processo). –
per verificare l'esistenza di un processo, chiamata kill (pid, 0). Questo succede quando il processo esiste, altrimenti fallisce. Attenzione al processo in esecuzione su una macchina diversa! – Arkadiy