60 votes

Comment créer une application à instance unique en C

Quelle serait votre suggestion pour créer une application à instance unique? Fichier verrouillé, mutex ou quoi?

68voto

Maxim Yegorushkin Points 29380

Un bon moyen est de:

#include <sys/file.h>

int pid_file = open("/var/run/whatever.pid", O_CREAT | O_RDWR, 0666);
int rc = flock(pid_file, LOCK_EX | LOCK_NB);
if(rc) {
    if(EWOULDBLOCK == errno)
        ; // another instance is running
}
else {
    // this is the first instance
}

Notez que le verrouillage permet d'ignorer obsolètes les fichiers pid (c'est à dire que vous n'avez pas à les supprimer). Lorsque l'application s'arrête pour une raison quelconque le système d'exploitation libère le verrou de fichier pour vous.

Les fichiers Pid ne sont pas très utiles car ils peuvent être obsolètes (le fichier existe mais le processus ne fonctionne pas). Par conséquent, l'exécutable de l'application elle-même peut être verrouillé à la place de la création et de verrouillage d'un fichier pid.

Une méthode plus avancée est de créer et lier un socket de domaine unix à l'aide d'un prédéfini socket nom. Lier réussit pour la première instance de votre application. Encore une fois, l'OS se délie la prise lorsque l'application s'arrête pour une raison quelconque. Lors de l' bind() d'échec d'une autre instance de l'application, connect() et utilisez cette douille pour passer ses arguments de ligne de commande à la première instance.

5voto

Binoy Points 21

Éviter basé sur un fichier de verrouillage

Il est toujours bon d'éviter un fichier basé sur le mécanisme de verrouillage permettant de mettre en œuvre l'instance du singleton d'une application. L'utilisateur peut toujours renommer le fichier de verrouillage d'un nom différent et exécutez à nouveau l'application comme suit:

mv fichier de verrouillage.pid lockfile1.pid

Où fichier de verrouillage.pid est le fichier de verrouillage basé sur ce qui est vérifié pour l'existence, avant l'exécution de l'application.

Donc, il est toujours préférable d'utiliser un schéma de verrouillage sur l'objet directement visibles seulement le noyau. Donc, tout ce qui a à faire avec un fichier système n'est pas fiable.

Donc, la meilleure option serait de se lier à un socket inet. Notez que les sockets de domaine unix résident dans le système de fichiers et ne sont pas fiables.

Alternativement, vous pouvez aussi le faire en utilisant DBUS.

5voto

Erik Points 38942

Pour les fenêtres, un objet noyau nommé (par exemple, CreateEvent, CreateMutex). Pour unix, un fichier pid - créez un fichier et écrivez-lui votre ID de processus.

3voto

Maciej Piechotka Points 3422

Cela semble ne pas être mentionné - il est possible de créer un mutex dans la mémoire partagée, mais il doit être marqué comme partagé par des attributs (non testé):

 pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_t *mutex = shmat(SHARED_MEMORY_ID, NULL, 0);
pthread_mutex_init(mutex, &attr);
 

Il existe également des sémaphores de mémoire partagée (mais je n’ai pas réussi à savoir comment en verrouiller un):

 int sem_id = semget(SHARED_MEMORY_KEY, 1, 0);
 

2voto

AProgrammer Points 31212

Cela dépend du problème que vous souhaitez, afin d'éviter de forcer votre application n'avoir qu'une seule instance et le champ sur lequel vous envisagez d'instances.

Pour un daemon -- la manière habituelle est d'avoir un /var/run/app.pid le fichier.

Pour l'application de l'utilisateur, j'ai eu plus de problèmes avec les applications qui m'a empêché de courir deux fois que d'être en mesure d'exécuter deux fois une application qui ne devrait pas avoir été courir de la sorte. Donc, la réponse à "pourquoi et sur l'étendue" est très important et sera probablement apporter de réponse précise sur le pourquoi et le champ d'application prévu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X