Lorsque je compile un programme à l'aide de la fonction POSIX sem_init()
, j'obtiens un avertissement de compilation (erreur car j'utilise normalement -Werror
) Que la fonction a été déconseillée lorsque je compiler sur Mac OS X 10.10.1 (Yosemite) avec GCC 4.9.1 ou la version de Clang (Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
) de XCode 6.1.1. Un rapide coup d'œil à /usr/include/sys/semaphore.h
Montre que la fonction a effectivement une balise __deprecated
Après sa déclaration, tout comme sem_getvalue()
et sem_destroy()
.
Des questions:
Étant donné qu'il n'y a aucun indice de dépréciation dans la spécification POSIX, pourquoi ces trois fonctions sont-elles considérées comme déconseillées sur Mac OS X?
Étant donné qu'ils sont obsolètes, quel est le remplacement et pourquoi le remplacement est-il préféré?
( J'ai vérifié Ask Different d'abord; il n'y a pas de questions étiquetées c et aucune question qui pose sur les appels système obsolètes - seulement les programmes. )
J'ai rencontré ce problème moi-même en essayant de porter une bibliothèque sur laquelle je travaillais sur OS X. J'ai cherché pendant un certain temps sans trouver de bonne réponse. Quand j'ai trouvé la réponse, j'étais un peu perturbé: la réponse est effectivement "si Apple a implémenté des sémaphores POSIX sans nom, combien de X Serves achèteriez-vous?" .
Pour résumer les raisons pour lesquelles elles sont obsolètes et pourquoi certaines fonctionnalités restent non implémentées:
sem_t
le type est difficileQuant à quoi faire à la place, je suis allé avec des sémaphores GCD. Quant à savoir pourquoi le remplacement est préféré: c'est la seule interface sémaphore native sans nom disponible sur Vanilla OS X. Apparemment, GCD les a aidés à vendre plus de X Serves. Je crains qu'il n'y ait pas de meilleure réponse.
Cependant, j'espère que certains codes seront utiles. Le résultat de tout cela est que vous devez effectivement implémenter votre propre interface de sémaphore portable:
#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
}
C'était l'ensemble minimal de fonctionnalités dont je me souciais; vos besoins peuvent varier. J'espère que cela vous sera utile.