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

Jon*_*ler 33 c macos posix

当我使用POSIX sem_init()函数编译程序时,我得到一个编译警告(因为我通常使用的错误-Werror),当我在Mac OS X 10.10.1(Yosemite)上使用GCC 4.9.1或版本的版本编译时,该函数已被弃用Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)来自XCode 6.1.1的Clang().快速浏览一下/usr/include/sys/semaphore.h表示此功能确实有__deprecated它的声明之后的标签,因为这样做 sem_getvalue()sem_destroy().

问题:

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

  2. 鉴于它们已被弃用,替代品是什么,为什么替代品更受欢迎?

(我确实首先检查了Ask Different ;没有标记问题,也没有问题询问已弃用的系统调用 - 只有程序.)

dho*_*dho 33

当我尝试移植我正在处理OS X的库时,我自己遇到了这个问题.我搜索了一段时间但没有找到一个好的答案.当我找到答案时,我有点不安:答案是有效的"如果Apple实施了POSIX未命名的信号量,你会购买多少个X服务器?" .

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

  • 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
}
Run Code Online (Sandbox Code Playgroud)

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

  • 我想我想要将destroy函数添加到集合中,但这是一个有用的起点.谢谢. (2认同)