web-dev-qa-db-fra.com

Pourquoi sem_init (), sem_getvalue (), sem_destroy () sont obsolètes sur Mac OS X - et qu'est-ce qui les remplace?

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:

  1. É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?

  2. É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. )

33
Jonathan Leffler

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:

  • L'annexe 9 de la spécification UNIX unique indique qu'il ne s'agit pas d'interfaces obligatoires
  • "Le code le plus portable" utilise les sémaphores SYSV
  • Compatibilité descendante avec les sémaphores nommés POSIX, qui partagent le sem_t le type est difficile

Quant à 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.

30
dho