Il s'avère qu'il n'existe aucun moyen de récupérer de manière fiable le sémaphore. Bien sûr, n'importe qui peut post_sem()
au sémaphore nommé pour que le compte augmente à nouveau au-delà de zéro, mais comment savoir quand une telle récupération est nécessaire ? L'API fournie est trop limitée et n'indique en aucune façon quand cela s'est produit.
Méfiez-vous des outils ipc également disponibles -- les outils communs ipcmk
, ipcrm
, et ipcs
sont uniquement pour les sémaphores SysV obsolètes. Ils ne fonctionnent spécifiquement pas avec les nouveaux sémaphores POSIX.
Mais il semble qu'il y ait d'autres choses qui peuvent être utilisées pour verrouiller les choses, que le système d'exploitation libère automatiquement lorsqu'une application meurt d'une manière qui ne peut pas être capturée dans un gestionnaire de signal. Deux exemples :un socket d'écoute lié à un port particulier ou un verrou sur un fichier spécifique.
J'ai décidé que le verrou sur un fichier était la solution dont j'avais besoin. Donc au lieu d'un sem_wait()
et sem_post()
appeler, j'utilise :
lockf( fd, F_LOCK, 0 )
et
lockf( fd, F_ULOCK, 0 )
Lorsque l'application se ferme de quelque manière que ce soit, le fichier est automatiquement fermé, ce qui libère également le verrou du fichier. Les autres applications clientes en attente du "sémaphore" sont alors libres de procéder comme prévu.
Merci pour votre aide, les gars.
Utilisez un fichier de verrouillage au lieu d'un sémaphore, un peu comme la solution de @Stéphane mais sans les appels flock(). Vous pouvez simplement ouvrir le fichier à l'aide d'un verrou exclusif :
//call to open() will block until it can obtain an exclusive lock on the file.
errno = 0;
int fd = open("/tmp/.lockfile",
O_CREAT | //create the file if it's not present.
O_WRONLY | //only need write access for the internal locking semantics.
O_EXLOCK, //use an exclusive lock when opening the file.
S_IRUSR | S_IWUSR); //permissions on the file, 600 here.
if (fd == -1) {
perror("open() failed");
exit(EXIT_FAILURE);
}
printf("Entered critical section.\n);
//Do "critical" stuff here.
//exit the critical section
errno = 0;
if (close(fd) == -1) {
perror("close() failed");
exit(EXIT_FAILURE);
}
printf("Exited critical section.\n");
C'est un problème typique lors de la gestion des sémaphores. Certains programmes utilisent un seul processus pour gérer l'initialisation/suppression du sémaphore. Habituellement, ce processus ne fait que cela et rien d'autre. Vos autres applications peuvent attendre que le sémaphore soit disponible. J'ai vu cela se faire avec l'API de type SYSV, mais pas avec POSIX. Semblable à ce que 'Canard ' mentionné, en utilisant le drapeau SEM_UNDO dans votre appel semop().
Mais, avec les informations que vous avez fournies, je vous suggère de ne pas utiliser de sémaphores. Surtout si votre processus risque d'être tué ou de tomber en panne. Essayez d'utiliser quelque chose que le système d'exploitation nettoiera automatiquement pour vous.