【问题标题】:Why are sem_init(), sem_getvalue(), sem_destroy() deprecated on Mac OS X — and what replaces them?为什么 sem_init(), sem_getvalue(), sem_destroy() 在 Mac OS X 上被弃用了——以及是什么替代了它们?
【发布时间】:2015-02-28 10:59:20
【问题描述】:

当我使用 POSIX sem_init() 函数编译程序时,我收到一个编译警告(错误,因为我通常使用 -Werror),当我在 Mac OS X 10.10.1 (Yosemite) 上编译时,该函数已被弃用使用 GCC 4.9.1 或 XCode 6.1.1 中的 Clang (Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)) 版本。快速查看/usr/include/sys/semaphore.h 表明该函数在其声明后确实有一个__deprecated 标记,就像这样 sem_getvalue()sem_destroy().

问题:

  1. 鉴于 POSIX 规范中没有暗示要弃用,为什么这三个函数在 Mac OS X 上被单独列出为弃用?

  2. 鉴于它们已被弃用,替代品是什么,为什么首选替代品?

我确实首先检查了Ask Different;没有标记为 的问题,也没有关于已弃用系统调用的问题——只有程序。

【问题讨论】:

  • @IskarJarak:这两个中的第一个似乎在实践中涵盖了我的问题,尽管仍有“为什么”(如“为什么 Mac OS X 不支持未命名的信号量?)”未解决。但这可能是最不容易回答的部分。由于我的代码没有编译,所以我没有从 sem_init() 函数得到 ENOSYS 错误。
  • 另一个或许更规范的答案来源可以通过“Mac 开发”的“核心操作系统”小节中的devforums.apple.com 找到。
  • @JonathanLeffler,在进程之间的共享内存中实现控制结构在开发和执行中都是相当大的开销。他们可能只是不想为在线程世界中没有太多用处的接口招致这种情况。他们处理这个问题的方式实际上很烦人,提供了一个只返回错误的界面。这再次表明,他们对 POSIX 的坚持只是表面上的。他们并没有真正致力于提供一个开放的环境。

标签: c c macos posix


【解决方案1】:

我自己在尝试将我正在开发的库移植到 OS X 时遇到了这个问题。我搜索了一段时间,但没有找到很好的答案。当我找到答案时,我有点忐忑:答案实际上是"if Apple implemented POSIX unnamed semaphores, how many X Serves would you buy?"

总结为什么它们被弃用以及为什么某些功能仍未实现:

  • 单一 UNIX 规范的附录 9 声明它们不是强制性接口
  • “最便携的代码”使用 SYSV 信号量
  • 与共享 sem_t 类型的 POSIX 命名信号量向后兼容很困难

至于做什么,我选择了 GCD 信号量。至于为什么首选替代品:它是 vanilla OS X 上唯一可用的本机未命名信号量接口。显然 GCD 帮助他们销售了更多 X Serves。恐怕没有更好的答案了。

但是,希望一些代码会有所帮助。所有这一切的结果是您必须有效地实现自己的可移植信号量接口:

#ifdef __APPLE__
#include <dispatch/dispatch.h>
#else
#include <semaphore.h>
#endif

struct rk_sema {
#ifdef __APPLE__
    dispatch_semaphore_t    sem;
#else
    sem_t                   sem;
#endif
};


static inline void
rk_sema_init(struct rk_sema *s, uint32_t value)
{
#ifdef __APPLE__
    dispatch_semaphore_t *sem = &s->sem;

    *sem = dispatch_semaphore_create(value);
#else
    sem_init(&s->sem, 0, value);
#endif
}

static inline void
rk_sema_wait(struct rk_sema *s)
{

#ifdef __APPLE__
    dispatch_semaphore_wait(s->sem, DISPATCH_TIME_FOREVER);
#else
    int r;

    do {
            r = sem_wait(&s->sem);
    } while (r == -1 && errno == EINTR);
#endif
}

static inline void
rk_sema_post(struct rk_sema *s)
{

#ifdef __APPLE__
    dispatch_semaphore_signal(s->sem);
#else
    sem_post(&s->sem);
#endif
}

这是我关心的最小功能集;您的需求可能会有所不同。希望这会有所帮助。

【讨论】:

  • 我想我想将销毁函数添加到集合中,但这是一个有用的起点。谢谢。
  • 太好了,你提供了我需要的东西。如果 Apple 没有实现未命名的信号量,那真的应该是一个错误。无论如何,在我按照您提供的内容更改代码后,它现在运行良好。
猜你喜欢
  • 2012-05-07
  • 1970-01-01
  • 1970-01-01
  • 2016-07-28
  • 2015-12-09
  • 1970-01-01
  • 2011-08-03
  • 2014-05-27
  • 2016-01-04
相关资源
最近更新 更多