Obviamente O_CREAT
y O_EXCL
no son necesarios al abrir un semáforo existente.
O_CREAT
es necesario al crear un nuevo semáforo.
O_EXCL
solo tiene sentido cuando se hace OR con O_CREAT
, especificando que si ya existe un semáforo con el nombre de pila, se devuelve un error.
Página del manual de Linux para sem_opendijo eso
Las definiciones de los valores de las banderas se pueden obtener incluyendo <fcntl.h>
pero no encontré ninguna bandera enfcntl.heso me dijo cómo abrir un semáforo existente.
Respuesta1
Considere el siguiente ejemplo:
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
const char* const sem_name = "lock.sem";
if (argc == 1) {
sem_t* const sem = sem_open(sem_name, O_CREAT, 0644, 0);
if (sem == NULL) {
perror("sem_open");
return 1;
}
sem_wait(sem); // Will block
sem_close(sem);
sem_unlink(sem_name);
} else {
sem_t* const sem = sem_open(sem_name, 0);
if (sem == NULL) {
perror("sem_open");
return 1;
}
sem_post(sem); // Will unblock the other process
sem_close(sem);
}
return 0;
}
Estoy usando el recuento de argumentos para controlar el comportamiento del programa.
Si no proporciono ningún parámetro (es decir, cuando argc == 1
), entonces el programa abrirá el semáforo y lo creará si aún no existe; inicializa el valor del semáforo en 0
. Luego hace una acción sem_wait()
sobre el sem
objeto. Dado que el semáforo se inicializó en 0
, esto hace que el proceso se bloquee.
Ahora, si ejecuto una segunda instancia de este mismo programa, pero esta vez con un número de argumentos distinto de cero (es decir, cuando argc != 1
), entonces el programa abrirá el semáforo, pero no lo creará si aún no existe. Tenga en cuenta que paso 0
el oflag
parámetro (es decir, no paso ninguna bandera). Luego, el programa hace un sem_post()
, incrementando el semáforo de 0
a 1
. Esto desbloquea el primer proceso. Ambos procesos cerrarán sus referencias al semáforo y finalizarán.
Si entiendo correctamente tu pregunta, el segundo caso es lo que estás buscando.
Si intento ejecutar el segundo caso primero (es decir, cuando no hay una instancia en ejecución del primer caso), obtengo:
$ ./a.out foo
sem_open: No such file or directory
Eso proviene de la llamada a perror()
porque no existe un semáforo con el nombre de pila.