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

当我使用POSIX sem_init()函数编译程序时,我得到一个编译警告(错误,因为我通常使用-Werror ),当我使用GCC 4.9在Mac OS X 10.10.1(Yosemite)上编译时,该函数已被弃用。 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 ;没有问题标记c ,也没有问题询问已弃用的系统调用 – 只有程序。

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

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

  • Single UNIX Specification的附录9声明它们不是强制接口
  • “大多数可移植代码”使用SYSV信号量
  • 与POSIX命名信号量的向后兼容性很难共享sem_t类型

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

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

 #ifdef __APPLE__ #include  #else #include  #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 } 

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