我可以删除使用 sem_open 创建的命名信号量吗?

Can I delete a named semaphore created with sem_open?

我正在试验命名信号量,但我对 sem_closesem_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 但它们似乎都没有删除信号量。

背景:我正在尝试将 NASA 核心飞行系统移植到 macOS。他们的 POSIX 实现使用 sem_ 调用,我试图了解是否可以通过一些小的修改让它们在 macOS 上工作。

由于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 -- remove a named semaphore

SYNOPSIS

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

DESCRIPTION
The named semaphore named name is removed. If the semaphore is in use by other processes, then name is immediately disassociated with the sema-phore, semaphore, phore, but the semaphore itself will not be removed until all references to it have been closed. Subsequent calls to sem_open() using name will refer to or create a new semaphore named name.

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

ERRORS
sem_unlink() succeeds unless:

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

 [ENAMETOOLONG]     name exceeded SEM_NAME_LEN characters.

 [ENOENT]           The named semaphore does not exist.

macOS Manual Pages | sem_unlink()