为什么 sem_init()、sem_getvalue()、sem_destroy() 在 Mac OS X 上被弃用 - 以及用什么来替代它们?

问题描述 投票:0回答:2

当我使用 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. 既然它们已被弃用,那么替代品是什么,为什么首选替代品?

我确实首先检查了询问不同;没有标记为的问题,也没有询问有关已弃用的系统调用的问题 - 只有程序。

c macos posix
2个回答
53
投票

当我尝试将我正在开发的库移植到 OS X 时,我自己也遇到了这个问题。我搜索了一段时间,但没有找到很好的答案。当我找到答案时,我有点不安:答案实际上是 “如果 Apple 实现 POSIX 未命名信号量,你会购买多少个 X Serves?”.

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

  • 单一 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
}

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


0
投票

只是为了在这里添加一些颜色, OS X 上的 sem_init 声称编译器报告“已弃用”,但实现实际上只是设置 errno 并返回

-1

真的很丢脸。如果您想在 Mac 上使用简单的信号量,您别无选择,只能对代码进行扩展。

© www.soinside.com 2019 - 2024. All rights reserved.