首页 > 解决方案 > 我可以删除使用 sem_open 创建的命名信号量吗?

问题描述

sem_close我正在尝试使用命名信号量,但我对and的行为有些不理解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但它们似乎都没有删除信号量。

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

标签: macossemaphore

解决方案


由于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 被删除。如果信号量正被其他进程使用,那么 name 会立即与信号量、信号量、信号量解除关联,但信号量本身不会被删除,直到对它的所有引用都已关闭。随后对 using 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.

ERRORS
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()


推荐阅读