Provided by: manpages-fr-dev_4.17.0-2_all bug

NOM

       pthread_cleanup_push,  pthread_cleanup_pop  -  push  and  pop  thread cancelation clean-up
       handlers

BIBLIOTHÈQUE

       POSIX threads library (libpthread, -lpthread)

SYNOPSIS

       #include <pthread.h>

       void pthread_cleanup_push(void (*routine)(void *), void *arg);
       void pthread_cleanup_pop(int execute);

DESCRIPTION

       These functions manipulate the  calling  thread's  stack  of  thread-cancelation  clean-up
       handlers. A clean-up handler is a function that is automatically executed when a thread is
       canceled (or in various other circumstances  described  below);  it  might,  for  example,
       unlock a mutex so that it becomes available to other threads in the process.

       La  fonction  pthread_cleanup_push() empile routine au sommet de la pile des gestionnaires
       de nettoyage. Quand routine sera appelée ultérieurement, arg sera passé en argument.

       La fonction pthread_cleanup_pop() dépile la routine au sommet de la pile des gestionnaires
       de nettoyage, et éventuellement l'exécute si l'argument execute est non nul.

       A  cancelation  clean-up  handler  is  popped from the stack and executed in the following
       circumstances:

       •  Quand un thread est annulé, tous les gestionnaires de nettoyage empilés sont dépilés et
          exécutés dans l'ordre inverse dans lequel ils ont été empilés.

       •  Quand  un  thread  se  termine  en  appelant pthread_exit(3), tous les gestionnaires de
          nettoyage sont exécutés comme décrit dans le point précédent. Il  faut  noter  que  les
          gestionnaires  de  nettoyage  ne sont pas appelés si le thread se termine par un return
          depuis la fonction de démarrage du thread.

       •  Quand un thread appelle pthread_cleanup_pop() avec un  argument  execute  non  nul,  le
          gestionnaire de nettoyage au sommet de la pile est dépilé et exécuté.

       POSIX.1  autorise  pthread_cleanup_push()   et  pthread_cleanup_pop()  à être implémentées
       comme des macros qui sont développées en du texte contenant « { » et « } » respectivement.
       Pour  cette raison, l'appelant doit s'assurer que les appels à ces fonctions sont appariés
       à l'intérieur d'une même fonction, et au même niveau d'imbriquement lexical.  En  d'autres
       termes,  un  gestionnaire  de  nettoyage n'est établi que pendant l'exécution d'une partie
       spécifique de code.

       Un appel à longjmp(3)  (resp. siglongjmp(3))  produit des résultats indéfinis si un  appel
       à   pthread_cleanup_push()    ou   pthread_cleanup_pop()    a  été  réalisé  sans  l'appel
       correspondant de la paire si  le  tampon  de  saut  a  été  rempli  par  setjmp(3)  (resp.
       sigsetjmp(3)).  De la même manière, un appel à longjmp(3) (resp. siglongjmp(3))  depuis un
       gestionnaire de nettoyage entraine des résultats indéfinis, sauf si le tampon  de  saut  a
       lui aussi été rempli dans setjmp(3)  (resp. sigsetjmp(3))  à l'intérieur du gestionnaire.

VALEUR RENVOYÉE

       Ces fonctions ne renvoient pas de valeur.

ERREURS

       Il n'y a pas d'erreur.

ATTRIBUTS

       Pour une explication des termes utilisés dans cette section, consulter attributes(7).

       ┌────────────────────────────────────────────────────────┬──────────────────────┬─────────┐
       │InterfaceAttributValeur  │
       ├────────────────────────────────────────────────────────┼──────────────────────┼─────────┤
       │pthread_cleanup_push(), pthread_cleanup_pop()           │ Sécurité des threads │ MT-Safe │
       └────────────────────────────────────────────────────────┴──────────────────────┴─────────┘

STANDARDS

       POSIX.1-2001, POSIX.1-2008.

NOTES

       Sous   Linux,   les   fonctions  pthread_cleanup_push()   et  pthread_cleanup_pop()   sont
       implémentées comme des macros qui sont développées en du texte contenant  « { »  et  « } »
       respectivement.  Cela signifie que les variables déclarées entre les appels appariés à ces
       fonctions ne seront visible qu'à l'intérieur de cet intervalle.

       POSIX.1 indique qu'utiliser return, break, continue, ou goto pour quitter prématurément un
       bloc   compris   entre   pthread_cleanup_push()   et  pthread_cleanup_pop()   entraine  un
       comportement indéfini. Les applications portables doivent l'éviter.

EXEMPLES

       The program below provides a simple example of the use of the functions described in  this
       page.   The   program   creates   a   thread   that   executes   a   loop   bracketed   by
       pthread_cleanup_push()  and pthread_cleanup_pop(). This loop increments a global variable,
       cnt,  once  each  second.  Depending on what command-line arguments are supplied, the main
       thread sends the other thread a cancelation request, or sets a global variable that causes
       the other thread to exit its loop and terminate normally (by doing a return).

       In  the  following shell session, the main thread sends a cancelation request to the other
       thread:

           $ ./a.out
           New thread started
           cnt = 0
           cnt = 1
           Canceling thread
           Called clean-up handler
           Thread was canceled; cnt = 0

       From the above, we see that the thread was canceled, and  that  the  cancelation  clean-up
       handler was called and it reset the value of the global variable cnt to 0.

       Lors de l'exécution suivante, le programme principal définit une variable globale qui fait
       que l'autre thread se termine normalement :

           $ ./a.out x
           New thread started
           cnt = 0
           cnt = 1
           Thread terminated normally; cnt = 2

       Dans la sortie, nous voyons que le gestionnaire de  nettoyage  n'a  pas  été  appelé  (car
       cleanup_pop_arg vaut 0), et la variable cnt n'a pas été réinitialisée.

       Lors de l'exécution suivante, le programme principal définit une variable globale qui fait
       que  l'autre  thread  se  termine  normalement,  et  fournit  une   valeur   non-nulle   à
       cleanup_pop_arg :

           $ ./a.out x 1
           New thread started
           cnt = 0
           cnt = 1
           Called clean-up handler
           Thread terminated normally; cnt = 0

       Dans  la  sortie, nous voyons que bien que le thread n'ait pas été annulé, le gestionnaire
       de nettoyage a été appelé, car l'argument fourni à pthread_cleanup_pop n'était pas nul.

   Source du programme

       #include <errno.h>
       #include <pthread.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/types.h>
       #include <unistd.h>

       #define handle_error_en(en, msg) \
               do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

       static int done = 0;
       static int cleanup_pop_arg = 0;
       static int cnt = 0;

       static void
       cleanup_handler(void *arg)
       {
           printf("Called clean-up handler\n");
           cnt = 0;
       }

       static void *
       thread_start(void *arg)
       {
           time_t curr;

           printf("New thread started\n");

           pthread_cleanup_push(cleanup_handler, NULL);

           curr = time(NULL);

           while (!done) {
               pthread_testcancel();           /* A cancelation point */
               if (curr < time(NULL)) {
                   curr = time(NULL);
                   printf("cnt = %d\n", cnt);  /* A cancelation point */
                   cnt++;
               }
           }

           pthread_cleanup_pop(cleanup_pop_arg);
           return NULL;
       }

       int
       main(int argc, char *argv[])
       {
           pthread_t thr;
           int s;
           void *res;

           s = pthread_create(&thread, NULL, thread_start, NULL);
           if (s != 0)
               handle_error_en(s, "pthread_create");

           sleep(2);           /* Allow new thread to run a while */

           if (argc > 1) {
               if (argc > 2)
                   cleanup_pop_arg = atoi(argv[2]);
               done = 1;

           } else {
               printf("Canceling thread\n");
               s = pthread_cancel(thr);
               if (s != 0)
                   handle_error_en(s, "pthread_cancel");
           }

           s = pthread_join(thr, &res);
           if (s != 0)
               handle_error_en(s, "pthread_join");

           if (res == PTHREAD_CANCELED)
               printf("Thread was canceled; cnt = %d\n", cnt);
           else
               printf("Thread terminated normally; cnt = %d\n", cnt);
           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       pthread_cancel(3),      pthread_cleanup_push_defer_np(3),       pthread_setcancelstate(3),
       pthread_testcancel(3), pthreads(7)

TRADUCTION

       La  traduction  française  de  cette  page  de  manuel  a  été créée par Christophe Blaess
       <https://www.blaess.fr/christophe/>, Stéphan  Rafin  <stephan.rafin@laposte.net>,  Thierry
       Vignaud  <tvignaud@mandriva.com>,  François Micaux, Alain Portal <aportal@univ-montp2.fr>,
       Jean-Philippe   Guérard   <fevrier@tigreraye.org>,   Jean-Luc   Coulon   (f5ibh)    <jean-
       luc.coulon@wanadoo.fr>,    Julien    Cristau    <jcristau@debian.org>,    Thomas   Huriaux
       <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin
       Duneau  <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis
       Barbier  <barbier@debian.org>,  David  Prévot  <david@tilapin.org>  et  Frédéric  Hantrais
       <fhantrais@gmail.com>

       Cette  traduction  est  une  documentation libre ; veuillez vous reporter à la GNU General
       Public  License  version 3  ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩   concernant   les
       conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

       Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un
       message à ⟨debian-l10n-french@lists.debian.org⟩.