Очевидно , что O_CREAT
и O_EXCL
не требуются при открытии существующего семафора.
O_CREAT
требуется при создании нового семафора.
O_EXCL
имеет смысл только при использовании оператора OR с O_CREAT
, указывая, что если семафор с указанным именем уже существует, то возвращается ошибка.
Страница руководства Linux для sem_openсказал, что
Определения значений флагов можно получить, включив <fcntl.h>
но я не нашел никакого флага вfcntl.hкоторый подсказал мне, как открыть существующий семафор.
решение1
Рассмотрим следующий пример:
#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;
}
Я использую количество аргументов для управления поведением программы.
Если я не укажу параметры (т. е. когда argc == 1
), то программа откроет семафор, создав его, если он еще не существует; она инициализирует значение семафора как 0
. Затем она выполняет a sem_wait()
на sem
объекте. Поскольку семафор был инициализирован как 0
, это приводит к блокировке процесса.
Теперь, если я запущу второй экземпляр этой же программы, но на этот раз с любым ненулевым числом аргументов (т. е. когда argc != 1
), то программа откроет семафор, но не создаст его, если он еще не существует. Обратите внимание, что я передаю 0
параметр oflag
(т. е. я не передаю никаких флагов). Затем программа выполняет sem_post()
, увеличивая семафор с 0
до 1
. Это разблокирует первый процесс. Оба процесса закроют свои ссылки на семафор и завершатся.
Если я правильно понял ваш вопрос, то вас интересует второй случай.
Если я попытаюсь сначала запустить второй случай (т.е. когда нет запущенного экземпляра первого случая), то я получу:
$ ./a.out foo
sem_open: No such file or directory
Это происходит из-за вызова, perror()
поскольку семафор с указанным именем не существует.