¿Qué hay de bloqueo basado en archivos (usando flock(2)
)? Estos se liberan automáticamente cuando el proceso que lo contiene muere.
programa de demostración:
#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;
}
salida (He truncan los PIDs y los tiempos de un bit para mayor claridad):
$ ./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
Lo que pasa es que el primer programa adquiere el bloqueo y se pone a duerme por 5 segundos. Después de 2 segundos, se inicia una segunda instancia del programa que bloquea al intentar adquirir el bloqueo. 3 segundos después, el primer programa segfaults (bash no te dice esto hasta más tarde) e inmediatamente, el segundo programa obtiene el bloqueo y continúa.
Estoy de acuerdo en general con la recomendación de semáforos, pero los semáforos POSIX realmente no resuelven el problema ya que tampoco registran el PID del proceso de bloqueo ni se desbloquean después de una muerte prematura. Rusty y torpe, aunque puedan ser semáforos SysV, hacen un seguimiento de los PID y pueden revertir cuando se los llama con la opción SEM_UNDO. – Duck