Obviamente O_CREAT
e O_EXCL
não são necessários ao abrir um semáforo existente.
O_CREAT
é necessário ao criar um novo semáforo.
O_EXCL
só tem sentido ao fazer OR com O_CREAT
, especificando que se um semáforo com o nome fornecido já existir, um erro será retornado.
Página de manual do Linux para sem_opendisse isso
As definições dos valores dos sinalizadores podem ser obtidas incluindo <fcntl.h>
mas não encontrei nenhuma bandeira emfcntl.hisso me disse como abrir um semáforo existente.
Responder1
Considere o seguinte exemplo:
#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;
}
Estou usando a contagem de argumentos para controlar o comportamento do programa.
Se eu não fornecer nenhum parâmetro (ou seja, quando argc == 1
), então o programa abrirá o semáforo, criando-o se ele ainda não existir; ele inicializa o valor do semáforo para 0
. Em seguida, ele faz um sem_wait()
no sem
objeto. Como o semáforo foi inicializado com 0
, isso faz com que o processo seja bloqueado.
Agora, se eu executar uma segunda instância deste mesmo programa, mas desta vez com qualquer número diferente de zero de argumentos (ou seja, quando argc != 1
), então o programa abrirá o semáforo, mas não o criará se ele ainda não existir. Observe aqui que eu passo 0
o oflag
parâmetro (ou seja, não estou passando nenhum sinalizador). O programa então faz um sem_post()
, incrementando o semáforo de 0
para 1
. Isso desbloqueia o primeiro processo. Ambos os processos fecharão suas referências ao semáforo e serão encerrados.
Se bem entendi sua pergunta, o segundo caso é o que você está procurando.
Se eu tentar executar o segundo caso primeiro (ou seja, quando não houver uma instância em execução do primeiro caso), obtenho:
$ ./a.out foo
sem_open: No such file or directory
Isso vem da chamada to perror()
porque não existe um semáforo com o nome fornecido.