Ответ 1
Я столкнулся с этой проблемой сам, пытаясь перенести библиотеку, над которой я работал, в OS X. Я искал какое-то время, не найдя отличный ответ. Когда я нашел ответ, я был немного взволнован: ответ действительно , если Apple внедрила неназванные семафоры POSIX, сколько X Serves вы купили?.
Подводя итог тому, почему они устарели и почему некоторые функции остаются нереализованными:
- В Приложении 9 Единой спецификации UNIX указано, что они не являются обязательными интерфейсами.
- "Самый переносимый код" использует семафоры SYSV
- Обратная совместимость с POSIX семафорами, которые разделяют тип
sem_t
, сложны
Что касается того, что делать, я пошел с семафорами GCD. Что касается того, почему замена предпочтительнее: это единственный собственный неназванный интерфейс семафора, доступный на ванильной ОС 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
}
Это был минимальный набор функций, о которых я заботился; ваши потребности могут отличаться. Надеюсь, это поможет.