Wie wäre es mit dateibasierten Sperren (mit flock(2)
)? Diese werden automatisch freigegeben, wenn der Prozess, der sie hält, stirbt.
Demo-Programm:
#include <stdio.h>
#include <time.h>
#include <sys/file.h>
void main() {
FILE * f = fopen("testfile", "w+");
printf("pid=%u time=%u Getting lock\n", getpid(), time(NULL));
flock(fileno(f), LOCK_EX);
printf("pid=%u time=%u Got lock\n", getpid(), time(NULL));
sleep(5);
printf("pid=%u time=%u Crashing\n", getpid(), time(NULL));
*(int *)NULL = 1;
}
Ausgang (Ich habe die PIDs und mal etwas für Klarheit gekürzt):
$ ./a.out & sleep 2 ; ./a.out
[1] 15
pid=15 time=137 Getting lock
pid=15 time=137 Got lock
pid=17 time=139 Getting lock
pid=15 time=142 Crashing
pid=17 time=142 Got lock
pid=17 time=147 Crashing
[1]+ Segmentation fault ./a.out
Segmentation fault
Was passiert, ist, dass das erste Programm die Sperre erfasst und beginnt zu Schlaf für 5 Sekunden. Nach 2 Sekunden wird eine zweite Instanz des Programms gestartet, die blockiert, während versucht wird, die Sperre zu erhalten. 3 Sekunden später, das erste Programm segfaults (bash sagt Ihnen das nicht bis später) und sofort, das zweite Programm bekommt die Sperre und geht weiter.
Stimmen Sie im Allgemeinen mit der Semaphor-Empfehlung überein, aber POSIX-Semaphoren lösen das Problem nicht wirklich, da sie auch nicht die PID des Sperrprozesses aufzeichnen oder bei vorzeitigem Tod entsperren. Rostig und ungeschickt, obwohl sie SysV-Semaphore sein können, behalten sie die PIDs im Auge und können sie wiederherstellen, wenn sie mit der Option SEM_UNDO aufgerufen werden. – Duck