为什么在Mac OS X上不推荐使用sem_init(),sem_getvalue(),sem_destroy() - 以及取代它们的原因是什么?

时间:2015-01-02 02:08:24

标签: c macos posix

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

  3. 我先检查了Ask Different;没有标记为的问题,也没有问过系统调用已被弃用的问题 - 只有程序。

1 个答案:

答案 0 :(得分:30)

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

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

  • Single UNIX Specification的附录9声明它们不是必需的接口
  • "大多数便携式代码"使用SYSV信号量
  • 与POSIX命名信号量的向后兼容性很难分享sem_t类型

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

但是,希望有些代码会有所帮助。所有这一切的结果是你实际上必须实现自己的便携式信号量接口:

#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
}

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