2011-01-17 7 views
10

Devo scrivere un programma che deve essere a conoscenza di un'altra istanza di se stesso in esecuzione su tale macchina e comunicare con esso, quindi morire. Voglio sapere se c'è un modo canonico di farlo in Linux.Come rendere un processo consapevole di altri processi dello stesso programma

Il mio primo pensiero è stato quello di scrivere un file contenente il PID del processo da qualche parte, e cercare quel file ogni volta che il programma viene eseguito, ma dov'è il posto e il nome "giusto" per quel file? C'è un modo migliore, o più "corretto"?

Quindi devo comunicare, dicendo che l'utente ha provato a eseguirlo, ma poiché c'è un'altra istanza, passerà il lavoro e uscirà. Ho pensato di inviare semplicemente un segnale, come SIGUSR1, ma questo non mi avrebbe permesso di inviare più informazioni, come il display X11 da cui l'utente eseguiva il secondo processo. Come inviare queste informazioni?

Il programma è collegato a Gtk, quindi una soluzione che utilizza la glib è OK.

risposta

10

Inserire il pid in un file è un modo comune per raggiungere questo obiettivo. Per i daemon ("programmi di sistema"), il luogo comune in cui inserire un file di questo tipo è /var/run/PROGRAM.pid. Per i programmi utente, metti il ​​file pid nascosto nell'home directory dell'utente (se il programma ha anche file di configurazione, quindi metti entrambi i file di configurazione e il file pid in una sottodirectory della directory home).

L'invio di informazioni all'istanza "master" è più comunemente ottenuto utilizzando socket di dominio Unix, noti anche come socket locali. Con un socket, non avrai bisogno di un file pid (se nessuno lo ascolta sul socket, il processo sa che è master).

+3

Un file pid da solo è praticamente inutile. Se l'applicazione si blocca, potrebbe non eliminare il suo file pid in modo che debba essere cancellato manualmente. Un'opzione migliore è quella di bloccare il file pid, perché il sistema operativo rilascia sempre il blocco quando il processo termina in qualche modo. Non puoi vedere quel blocco però facendo 'ls -la'. È sufficiente un solo socket di dominio unix. –

+0

@Maxim: False. 'Unlink (...)' cancella il file dopo che il file è stato chiuso. Quindi 'fd = open (path, ...); unlink (path); 'è il solito trucco per avere un file temporaneo. – Alexandru

+0

@Alexandru: Quasi, hai perso il fatto che stavamo discutendo di file pid, non di file temporanei. Il file pid non deve essere rimosso prima che l'applicazione termini. –

9

socket di dominio Unix. Avere la prima istanza crearne una in una directory temporanea, quindi fare in modo che altre istanze comunichino con essa tramite quella.

+2

Forse non una directory temporanea -/var/run è abbastanza comune per i file socket. –

5

Scrivere un file PID è un approccio comune. Controlla la libreria pidfile(3).

1

Ci sono molti modi per farlo. Il modo in cui hai proposto (utilizzando un file contenente il PID) è valido e viene utilizzato da molte applicazioni.

Alcune volte il file di configurazione dell'applicazione contiene il percorso per il file PID, altre volte viene utilizzato un percorso con hardcoded. Di solito l'applicazione inserisce il file PID in /tmp, in /var (se viene eseguito con uid 0) o nella loro directory locale (~/.application/).

Non avrebbe un suggerimento generale su dove inserire il tuo file PID, basta scegliere il luogo che preferisci.

2

Linux ha l'equivalente di un mutex o di un semaforo con nome? Quindi puoi controllare se è "bloccato" e quindi avvisare l'utente che ne ha già uno là fuori e chiuderlo fuori?

ha senso da questo collegamento? http://www.linuxquestions.org/questions/programming-9/named-mutex-in-linux-296816/

+0

I semafori denominati sembrano funzionare come un modo per affrontare il problema di più istanze, anche se è piuttosto poco ortodosso. – lvella

+2

Mentre funziona, è piuttosto brutto in quanto lo spazio dei nomi è condiviso tra tutti i processi sulla macchina, e qualsiasi altro utente potrebbe eseguire il programma aprendo un semaforo con lo stesso nome. Personalmente non userei mai POSIX denominati semafori/memoria condivisa senza nomi randomizzati, e comunicando il nome attraverso un altro canale sicuro non scrivibile tranne da un processo con i privilegi giusti. –

1

È possibile utilizzare un socket di dominio Unix; Penso che molte applicazioni (che non usano un sistema di livello superiore come DCOP o DBUS) le utilizzino.

Se si è soddisfatti del fatto che sia specifico per Linux, è possibile utilizzare un socket unix "spazio dei nomi astratto"; questi sono piuttosto carini perché non hanno bisogno di esistere nel filesystem.

Se il programma è orientato all'utente, dovrebbe probabilmente essere multiutente; un utente non dovrebbe essere in grado di attivare il comportamento nella copia di un altro utente dell'app, e la sicurezza deve essere in atto per garantire che gli utenti non possano fare a vicenda Facilmente l'un l'altro (Esempio: se la copia del programma dell'utente si blocca, si ferma all'utente B sta iniziando?).

+0

Penso che mantenere i file all'interno della casa dell'utente impedirà di interferire con un altro utente. – lvella

+0

Sì, questa è una possibile implementazione. – MarkR

Problemi correlati