GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo recupero un semáforo cuando el proceso que lo redujo a cero falla?

Resulta que no hay una forma de recuperar el semáforo de manera confiable. Claro, cualquiera puede post_sem() al semáforo nombrado para que el conteo aumente más allá de cero nuevamente, pero ¿cómo saber cuándo se necesita tal recuperación? La API proporcionada es demasiado limitada y no indica de ninguna manera cuándo sucedió esto.

Tenga cuidado con las herramientas ipc también disponibles:las herramientas comunes ipcmk , ipcrm y ipcs son solo para los semáforos SysV obsoletos. Específicamente, no funcionan con los nuevos semáforos POSIX.

Pero parece que hay otras cosas que se pueden usar para bloquear cosas, que el sistema operativo libera automáticamente cuando una aplicación muere de una manera que no puede ser capturada en un controlador de señal. Dos ejemplos:un socket de escucha vinculado a un puerto en particular o un bloqueo en un archivo específico.

Decidí que el bloqueo de un archivo es la solución que necesitaba. Así que en lugar de un sem_wait() y sem_post() llama, estoy usando:

lockf( fd, F_LOCK, 0 )

y

lockf( fd, F_ULOCK, 0 )

Cuando la aplicación sale de alguna manera, el archivo se cierra automáticamente, lo que también libera el bloqueo del archivo. Otras aplicaciones cliente que esperan el "semáforo" pueden continuar libremente como se esperaba.

Gracias por la ayuda, chicos.


Use un archivo de bloqueo en lugar de un semáforo, como la solución de @Stéphane pero sin las llamadas a flock(). Simplemente puede abrir el archivo usando un bloqueo exclusivo:

//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");

Este es un problema típico cuando se manejan semáforos. Algunos programas utilizan un único proceso para gestionar la inicialización/eliminación del semáforo. Por lo general, este proceso hace solo esto y nada más. Sus otras aplicaciones pueden esperar hasta que el semáforo esté disponible. He visto esto hecho con la API de tipo SYSV, pero no con POSIX. Similar a lo que 'Duck ' mencionado, usando el indicador SEM_UNDO en su llamada semop().


Pero, con la información que ha proporcionado, le sugiero que no use semáforos. Especialmente si su proceso está en peligro de morir o bloquearse. Intente usar algo que el sistema operativo limpiará automáticamente por usted.


Linux
  1. ¿Nuevo proceso principal cuando muere el proceso principal?

  2. ¿Cómo agregar la salida a un archivo?

  3. ¿Cómo recuperar un archivo eliminado si todavía está abierto por algún proceso?

  4. ¿Cómo encontrar el administrador de archivos predeterminado?

  5. ¿Cómo redirigir la salida de un comando a un archivo cuando el comando solicitará las entradas del usuario?

Cómo recuperar un archivo eliminado en Linux

Cómo encontrar el paquete que proporciona un archivo específico en Linux

¿Cómo recuperarse después de que Kate se estrella?

¿Cómo matar el proceso que mantiene el bloqueo Apt?

¿Cómo encontrar el proceso con el máximo de descriptores de archivo?

¿Cómo ejecutar un archivo .sh cuando comienza la sesión?