Provided by: manpages-fr-extra_20080618_all bug

NOM

       pthread_cleanup_push,                              pthread_cleanup_pop,
       pthread_cleanup_push_defer_np,     pthread_cleanup_pop_restore_np     -
       Installer et enlever des gestionnaires de nettoyage

SYNOPSIS

       #include <pthread.h>

       void pthread_cleanup_push(void (*routine) (void *), void *arg);

       void pthread_cleanup_pop(int execute);

       void   pthread_cleanup_push_defer_np(void  (*routine)  (void  *),  void
       *arg);

       void pthread_cleanup_pop_restore_np(int execute);

DESCRIPTION

       Les gestionnaires de nettoyage sont des  fonctions  qui  sont  appelées
       lorsqu’un  thread  se  termine,  soit  en appelant pthread_exit(3) soit
       parce qu’il a été annulé. Les gestionnaires de nettoyage sont installés
       et enlevés à la manière d’une pile.

       Le  rôle  d’un  gestionnaire de nettoyage est de libérer les ressources
       acquises par un thread lorsque son exécution s’achève. En  particulier,
       si  un thread se termine ou est annulé alors qu’il verrouille un mutex,
       ce dernier restera verrouillé pour toujours, empêchant d’autres threads
       de  s’exécuter  normalement.  La  meilleure manière d’empêcher cela est
       d’installer un gestionnaire de  nettoyage  dont  la  fonction  sera  de
       déverrouiller   le   mutex.  Les  gestionnaires  de  nettoyage  peuvent
       également être utilisés pour libérer des blocs de mémoire  alloués  par
       malloc(3)  ou  fermer des descripteurs de fichiers lorsque le thread se
       termine.

       pthread_cleanup_push() installe la fonction routine avec  le  paramètre
       arg en tant que gestionnaire de nettoyage. À partir de ce point jusqu’à
       un appel à la fonction pthread_cleanup_pop(), la fonction routine  sera
       appelée  avec  le  paramètre arg quand le thread se terminera, soit par
       pthread_exit(3),  soit  à  la  suite  d’une  annulation.  Si  plusieurs
       gestionnaires  de  nettoyage  ont  été enregistrés, ils seront exécutés
       dans l’ordre LIFO (dernier entré, premier sorti).

       pthread_cleanup_pop() désactive le dernier  gestionnaire  de  nettoyage
       installé.  Si  le  paramètre execute ne vaut pas 0, ce gestionnaire est
       exécuté en appelant la fonction routine avec les paramètres arg. Si  le
       paramètre  execute vaut 0, le gestionnaire est seulement désactivé mais
       pas exécuté.

       Les paires de fonctions pthread_cleanup_push() et pthread_cleanup_pop()
       doivent  être  exécutées  dans  la même fonction au même niveau du bloc
       lexical. En fait, pthread_cleanup_push() et pthread_cleanup_pop()  sont
       des   macros :  l’expansion  de  pthread_cleanup_push()  introduit  une
       accolade ouvrante « { » fermée  par  l’accolade  « } »  introduite  par
       l’expansion de la macro correspondante, pthread_cleanup_pop().

       pthread_cleanup_push_defer_np()  est  une  extension  non  portable qui
       combine  pthread_cleanup_push()   et   pthread_setcanceltype(3).   Elle
       enregistre    le    gestionnaire    de    nettoyage   comme   le   fait
       pthread_cleanup_push(), mais sauvegarde également le mode  d’annulation
       courant  et  le  passe  en  mode  d’annulation retardée. Cela permet de
       s’assurer que le mécanisme de nettoyage est efficace même si le  thread
       fonctionne en mode d’annulation asynchrone.

       pthread_cleanup_pop_restore_np()  dépile  le  dernier  gestionnaire  de
       nettoyage enregistré par pthread_cleanup_push_defer_np(),  et  restaure
       le       mode      d’annulation      à      sa      valeur      lorsque
       pthread_cleanup_push_defer_np() a été appelée.

       pthread_cleanup_push_defer_np()   et   pthread_cleanup_pop_restore_np()
       doivent  être exécutées par paire, dans le même bloc, au même niveau et
       ne peuvent pas être entrelacées avec une autre paire.

       La séquence suivante

              pthread_cleanup_push_defer_np(routine, arg);
              pthread_cleanup_pop_defer_np(execute);

       est fonctionnellement équivalente (mais plus compacte et plus efficace)
       à

              { int oldtype;
                pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
                pthread_cleanup_push(routine, arg);
                ...
                pthread_cleanup_pop(execute);
                pthread_setcanceltype(oldtype, NULL);
              }

VALEUR RENVOYÉE

       Aucune.

ERREURS

       Aucune.

AUTEUR

       Xavier Leroy <Xavier.Leroy@inria.fr>

VOIR AUSSI

       pthread_exit(3), pthread_cancel(3), pthread_setcanceltype(3)

EXEMPLE

       Voici  comment  verrouiller  un  mutex mut, de telle manière qu’il sera
       déverrouillé si le thread est annulé, alors que mut est verrouillé :

              pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
              pthread_mutex_lock(&mut);
              /* do some work */
              pthread_mutex_unlock(&mut);
              pthread_cleanup_pop(0);

       Les deux dernières lignes peuvent être remplacées par :

              pthread_cleanup_pop(1);

       Remarquez que le code ci-dessus n’est fiable  qu’en  mode  d’annulation
       retardée   (voyez   pthread_setcanceltype(3)).   En  mode  d’annulation
       asynchrone, une annulation peut intervenir entre pthread_cleanup_push()
       et    pthread_mutex_lock(),    ou   entre   pthread_mutex_unlock()   et
       pthread_cleanup_pop(), résultant dans les deux cas en un thread tentant
       de  déverrouiller  un mutex non verrouillé par le thread courant. C’est
       la principale raison pour laquelle le mode d’annulation asynchrone  est
       si problématique à utiliser.

       Afin  que  le  code  précédent  fonctionne  aussi  en mode d’annulation
       asynchrone,  il  doit  passer  en  mode  d’annulation   retardée   pour
       verrouiller et déverrouiller le mutex :

              pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
              pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
              pthread_mutex_lock(&mut);
              /* do some work */
              pthread_cleanup_pop(1);
              pthread_setcanceltype(oldtype, NULL);

       Le  code  ci-dessus  peut  être récrit de manière plus compacte et plus
       efficace    en    utilisant    les     extensions     non     portables
       pthread_cleanup_push_defer_np() et pthread_cleanup_pop_restore_np() :

              pthread_cleanup_push_restore_np(pthread_mutex_unlock, (void *) &mut);
              pthread_mutex_lock(&mut);
              /* do some work */
              pthread_cleanup_pop_restore_np(1);

TRADUCTION

       Cette  page  de  manuel a été traduite par Thierry Vignaud <tvignaud AT
       mandriva DOT com> en 2000 et  révisée  par  Alain  Portal  <aportal  AT
       univ-montp2  DOT  fr>  en  2006.   La  version présente dans Debian est
       maintenue par les membres de la liste <debian-l10n-french AT lists  DOT
       debian  DOT  org>.  Veuillez signaler toute erreur de traduction par un
       rapport de bogue sur le paquet manpages-fr-extra.

                                 LinuxThreads               PTHREAD_CLEANUP(3)