Es stellt sich heraus, dass es keine Möglichkeit gibt, die Semaphore zuverlässig wiederherzustellen. Sicher, jeder kann post_sem()
an die benannte Semaphore, um die Zählung wieder über Null hinaus zu erhöhen, aber wie kann man feststellen, wann eine solche Wiederherstellung erforderlich ist? Die bereitgestellte API ist zu begrenzt und zeigt in keiner Weise an, wann dies passiert ist.
Hüten Sie sich vor den ebenfalls verfügbaren IPC-Tools - den allgemeinen Tools ipcmk
, ipcrm
, und ipcs
sind nur für die veralteten SysV-Semaphoren. Sie funktionieren insbesondere nicht mit den neuen POSIX-Semaphoren.
Aber es sieht so aus, als ob es andere Dinge gibt, die zum Sperren von Dingen verwendet werden können, die das Betriebssystem automatisch freigibt, wenn eine Anwendung auf eine Weise stirbt, die nicht in einem Signalhandler abgefangen werden kann. Zwei Beispiele:ein Listening-Socket, das an einen bestimmten Port gebunden ist, oder eine Sperre für eine bestimmte Datei.
Ich entschied, dass die Sperre einer Datei die Lösung ist, die ich brauchte. Also statt einer sem_wait()
und sem_post()
Anruf, ich verwende:
lockf( fd, F_LOCK, 0 )
und
lockf( fd, F_ULOCK, 0 )
Wenn die Anwendung auf irgendeine Weise beendet wird, wird die Datei automatisch geschlossen, wodurch auch die Dateisperre aufgehoben wird. Andere Client-Apps, die auf die "Semaphore" warten, können dann wie erwartet fortfahren.
Danke für die Hilfe, Leute.
Verwenden Sie eine Sperrdatei anstelle eines Semaphors, ähnlich wie die Lösung von @Stéphane, jedoch ohne die Aufrufe von flock(). Sie können die Datei einfach mit einer exklusiven Sperre öffnen:
//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");
Dies ist ein typisches Problem bei der Verwaltung von Semaphoren. Einige Programme verwenden einen einzigen Prozess, um die Initialisierung/Löschung des Semaphors zu verwalten. Normalerweise macht dieser Prozess genau das und sonst nichts. Ihre anderen Anwendungen können warten, bis die Semaphore verfügbar ist. Ich habe dies mit der SYSV-Typ-API gesehen, aber nicht mit POSIX. Ähnlich wie bei 'Duck ' erwähnt, indem Sie das SEM_UNDO-Flag in Ihrem semop()-Aufruf verwenden.
Aber Mit den von Ihnen bereitgestellten Informationen würde ich vorschlagen, dass Sie keine Semaphoren verwenden. Vor allem, wenn Ihr Prozess Gefahr läuft, beendet zu werden oder abzustürzen. Versuchen Sie, etwas zu verwenden, das das Betriebssystem automatisch für Sie bereinigt.