为什么 sem_init()、sem_getvalue()、sem_destroy() 在 Mac OS X 上被弃用——什么替代了它们?
Why are sem_init(), sem_getvalue(), sem_destroy() deprecated on Mac OS X — and what replaces them?
当我使用 POSIX sem_init()
函数编译程序时,我收到一个编译警告(错误,因为我通常使用 -Werror
)当我使用 GCC 4.9.1 或来自 XCode 6.1.1 的 Clang (Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
) 版本在 Mac OS X 10.10.1 (Yosemite) 上编译。快速查看 /usr/include/sys/semaphore.h
表明该函数在其声明后确实有一个 __deprecated
标记,就像
sem_getvalue()
和
sem_destroy()
.
问题:
既然在 POSIX 规范中没有任何弃用的提示,为什么在 Mac OS X 上将这三个函数挑出来弃用?
鉴于它们已被弃用,替代品是什么,为什么首选替代品?
(我确实检查了 Ask Different first; there are no questions tagged c 并且没有询问有关已弃用系统调用的问题 — 只有程序。)
我 运行 在尝试将我正在研究的库移植到 OS X 时自己遇到了这个问题。我搜索了一段时间但没有找到很好的答案。当我确实找到答案时,我有点不安:答案实际上是 "if Apple implemented POSIX unnamed semaphores, how many X Serves would you buy?".
总结它们被弃用的原因以及某些功能仍未实现的原因:
- 单一 UNIX 规范的附录 9 声明它们不是强制接口
- "Most portable code" 使用 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
}
这是我关心的最少功能集;您的需求可能会有所不同。希望这对您有所帮助。
当我使用 POSIX sem_init()
函数编译程序时,我收到一个编译警告(错误,因为我通常使用 -Werror
)当我使用 GCC 4.9.1 或来自 XCode 6.1.1 的 Clang (Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
) 版本在 Mac OS X 10.10.1 (Yosemite) 上编译。快速查看 /usr/include/sys/semaphore.h
表明该函数在其声明后确实有一个 __deprecated
标记,就像
sem_getvalue()
和
sem_destroy()
.
问题:
既然在 POSIX 规范中没有任何弃用的提示,为什么在 Mac OS X 上将这三个函数挑出来弃用?
鉴于它们已被弃用,替代品是什么,为什么首选替代品?
(我确实检查了 Ask Different first; there are no questions tagged c 并且没有询问有关已弃用系统调用的问题 — 只有程序。)
我 运行 在尝试将我正在研究的库移植到 OS X 时自己遇到了这个问题。我搜索了一段时间但没有找到很好的答案。当我确实找到答案时,我有点不安:答案实际上是 "if Apple implemented POSIX unnamed semaphores, how many X Serves would you buy?".
总结它们被弃用的原因以及某些功能仍未实现的原因:
- 单一 UNIX 规范的附录 9 声明它们不是强制接口
- "Most portable code" 使用 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
}
这是我关心的最少功能集;您的需求可能会有所不同。希望这对您有所帮助。