Могу ли я удалить именованный семафор, созданный с помощью sem_open? - PullRequest
1 голос
/ 07 января 2020

Я экспериментирую с именованными семафорами, и есть кое-что, чего я не понимаю в поведении sem_close и sem_destroy. В моем примере это выглядит так, как будто созданный семафор не удаляется.

#include <iostream>

#include <semaphore.h>

int main() {
  char sem_name[] = "/sem-1";

  {
    sem_t *sptr = sem_open(sem_name, O_CREAT, 0644, 0);
    if (sptr != SEM_FAILED) {
      printf("sem_open success\n");

      // neither of these works
      sem_close(sptr);
      // sem_destroy(sptr);
    } else {
      printf("sem_open error #1: %s\n", strerror(errno));
    }
  }

  sem_t *sptr = sem_open(sem_name, O_CREAT | O_EXCL, 0644, 0);
  printf("sem_open error #2: %s\n", strerror(errno));
  assert(sptr != SEM_FAILED);

  return 0;
}

Вывод:

sem_open success
sem_open error #2: File exists
Assertion failed: (sptr != SEM_FAILED), function main, file /tmp/delete_me/main.cpp, line 22.

Я ожидаю, что утверждение не будет выполнено, а также ошибка № 2 не отображается.

Кроме того, macOS говорит, что метод sem_destroy устарел, но я все еще использую и sem_close(), и sem_destroy, но они оба, похоже, не удаляют семафор.

Справочная информация: я пытаюсь перенести Core Flight System NASA на macOS. Их реализация POSIX использует вызовы sem_, и я пытаюсь понять, смогу ли я заставить их работать на macOS с некоторыми незначительными изменениями.

1 Ответ

1 голос
/ 07 января 2020

Поскольку macOS распознает только named семафоров, использование sem_destroy() не будет работать. sem_destroy() уничтожает безымянный семафор по адресу, указанному в sem. Только семафор, инициализированный sem_init(), должен быть уничтожен с помощью sem_destroy().

Вероятно, вы можете решить эту проблему, используя sem_unlink:

...
sem_close(sptr);
sem_unlink(sem_name);
...

SEM_UNLINK (2)

NAME
sem_unlink - удалить именной семафор

СИНОПСИС

 #include <semaphore.h>
 int sem_unlink(const char *name);

ОПИСАНИЕ
Именованный Семафор с именем name удаляется. Если семафор используется другими процессами, то имя немедленно отсоединяется от семафора, семафора, фора, но сам семафор не будет удален, пока все ссылки на него не будут закрыты. Последующие вызовы sem_open() с использованием имени будут ссылаться или создавать новый семафор с именем name.

 If successful, `sem_unlink()` will return 0.  Otherwise, -1 is returned and
 errno is set, and the state of the semaphore is unchanged.

ОШИБКИ
sem_unlink() завершатся успешно, если:

 [EACCES]           Permission is denied to be remove the semaphore.

 [ENAMETOOLONG]     name exceeded SEM_NAME_LEN characters.

 [ENOENT]           The named semaphore does not exist.

macOS Страницы руководства | sem_unlink ()

...