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

NOM

       pthread_create – Créer un nouveau thread

BIBLIOTHÈQUE

       Bibliothèque de threads POSIX (libpthread, -lpthread)

SYNOPSIS

       #include <pthread.h>

       int pthread_create(pthread_t *restrict thread,
                          const pthread_attr_t *restrict attr,
                          void *(*start_routine)(void *),
                          void *restrict arg);

DESCRIPTION

       La fonction pthread_create() démarre un nouveau thread (processus léger) dans le processus
       appelant. Le nouveau thread commence par appeler start_routine() ;  arg  est  passé  comme
       unique argument de start_routine().

       Le nouveau thread se termine d'une des manières suivantes :

       -  Il  appelle pthread_exit(3), en indiquant une valeur de sortie qui sera disponible pour
          un autre thread du même processus qui appelle pthread_join(3).

       -  Il sort de la routine start_routine(). C'est équivalent à appeler pthread_exit(3)  avec
          la valeur fournie à l'instruction return.

       -  Il est annulé (voir pthread_cancel(3)).

       -  Un  des  threads du processus appelle exit(3) ou le thread principal sort de la routine
          main() ce qui entraîne l'arrêt de tous les threads du processus.

       L'argument attr pointe sur une  structure  pthread_attr_t  dont  le  contenu  est  utilisé
       pendant  la  création  des  threads pour déterminer les attributs du nouveau thread. Cette
       structure est initialisée avec pthread_attr_init(3) et les fonctions similaires.  Si  attr
       est NULL, alors le thread est créé avec les attributs par défaut.

       Avant  de  rendre  la  main,  un  appel  réussi à pthread_create() stocke l'identifiant du
       nouveau thread dans le tampon pointé par thread.  Cet  identifiant  est  utilisé  pour  se
       référer à ce thread dans les appels ultérieurs aux autres fonctions de pthreads.

       Le   nouveau   thread   hérite  d'une  copie  du  masque  de  signal  du  thread  créateur
       (pthread_sigmask(3)). L'ensemble des signaux en attente pour le nouveau  thread  est  vide
       (sigpending(2)).  Le  nouveau  thread  n'hérite  pas  de  la  pile  spécifique  de signaux
       (sigaltstack(2)) du thread appelant.

       Le nouveau thread hérite de l'environnement  en  virgule  flottante  (fenv(3))  du  thread
       appelant.

       La    valeur    initiale    de   l'horloge   CPU   du   nouveau   thread   est   0   (voir
       pthread_getcpuclockid(3)).

   Détails spécifiques à Linux
       Le nouveau thread hérite de copies des ensembles des capacités (voir  capabilities(7))  et
       des masques d'affinité CPU (consultez sched_setaffinity(2)) du thread appelant.

VALEUR RENVOYÉE

       En  cas  de réussite, pthread_create() renvoie 0 ; en cas d'erreur, elle renvoie un numéro
       d'erreur, et le contenu de *thread est indéfini.

ERREURS

       EAGAIN Ressources insuffisantes pour créer un nouveau thread.

       EAGAIN Une limite système sur le nombre de  threads  a  été  atteinte.  Plusieurs  limites
              pourraient  déclencher  cette  erreur : la limite de ressources souple RLIMIT_NPROC
              (définie à l’aide setrlimit(2)), qui limite le nombre de processus et  threads  par
              identifiant  d’utilisateur  réel, a été atteinte ; la limite système imposée par le
              noyau sur le nombre total de processus et threads, /proc/sys/kernel/threads-max,  a
              été    atteinte    (consultez   proc(5)) ;   ou   le   nombre   maximal   de   PID,
              /proc/sys/kernel/pid_max, a été atteint (consultez proc(5)).

       EINVAL Paramètres incorrects dans attr.

       EPERM  Permissions  insuffisantes  pour  définir  la  politique  d'ordonnancement  et  les
              paramètres spécifiés dans attr.

ATTRIBUTS

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

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

STANDARDS

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

NOTES

       Consultez  pthread_self(3)  pour  des  informations  plus  détaillées sur l'identifiant de
       thread renvoyé dans *thread par pthread_create(). Sauf si une  politique  d'ordonnancement
       temps-réel  est  employée, après un appel à pthread_create(), on ne sait pas quel thread —
       l'appelant ou le nouveau thread — sera exécuté ensuite.

       Un thread peut être dans un état soit joignable (joinable), soit détaché (detached). Si un
       thread  est  joignable,  un autre thread peut appeler pthread_join(3) pour attendre que ce
       thread se termine et récupérer sa valeur de sortie. Ce n'est que quand un  thread  terminé
       et  joignable  a  été  joint  que  ses ressources sont rendues au système. Quand un thread
       détaché se termine, ses ressources sont automatiquement rendues au système : il n'est  pas
       possible  de joindre un tel thread afin d'en obtenir la valeur de sortie. Mettre un thread
       dans  l'état  détaché  est  pratique  pour  certains  types  de  threads  de  démon   dont
       l'application  n'a  pas  à  se  préoccuper  de la valeur de sortie. Par défaut, un nouveau
       thread  est  créé  dans  l'état  joignable,  à  moins  qu'attr  n'ait  été  modifié  (avec
       pthread_attr_setdetachstate(3)) pour créer le thread dans un état détaché.

       Avec  l'implémentation  NPTL,  si  la  limite  souple  RLIMIT_STACK  a  une  valeur  autre
       qu'« unlimited » au moment  le programme a démarré, elle détermine la taille de la  pile
       par  défaut  pour les nouveaux threads. Afin d'obtenir une taille de pile différente de la
       valeur par défaut, il faut appeler pthread_attr_setstacksize(3) avec la  valeur  souhaitée
       sur  l'argument attr utilisé pour créer un thread. Si la limite de ressources RLIMIT_STACK
       a la valeur « unlimited », une valeur dépendant de l'architecture  est  utilisée  pour  la
       taille de la pile. Voici cette valeur pour quelques architectures :

              ┌─────────────┬───────────────────────────┐
              │ArchitectureTaille de pile par défaut │
              ├─────────────┼───────────────────────────┤
              │i386         │                      2 Mo │
              ├─────────────┼───────────────────────────┤
              │IA-64        │                     32 Mo │
              ├─────────────┼───────────────────────────┤
              │PowerPC      │                      4 Mo │
              ├─────────────┼───────────────────────────┤
              │S/390        │                      2 Mo │
              ├─────────────┼───────────────────────────┤
              │Sparc-32     │                      2 Mo │
              ├─────────────┼───────────────────────────┤
              │Sparc-64     │                      4 Mo │
              ├─────────────┼───────────────────────────┤
              │x86_64       │                      2 Mo │
              └─────────────┴───────────────────────────┘

BOGUES

       Dans  l'implémentation  obsolète  LinuxThreads,  chacun des threads dans un processus a un
       identifiant de processus différent, ce qui est en violation des spécifications  POSIX  sur
       les  threads  et  est  la  cause  de  nombreuses  non-conformité  au  standard.  Consultez
       pthreads(7).

EXEMPLES

       Le programme ci-dessous montre l'utilisation  de  pthread_create(),  ainsi  qu'un  certain
       nombre d'autres fonctions de l'API pthreads.

       Lors  de  l'exécution suivante, sur un système avec l'implémentation NPTL, la taille de la
       pile vaut par défaut la valeur renvoyée par la  limite  de  la  ressource  « stack  size »
       (taille de la pile) :

           $ ulimit -s
           8192            # The stack size limit is 8 MB (0x800000 bytes)
           $ ./a.out hola salut servus
           Thread 1: top of stack near 0xb7dd03b8; argv_string=hola
           Thread 2: top of stack near 0xb75cf3b8; argv_string=salut
           Thread 3: top of stack near 0xb6dce3b8; argv_string=servus
           Joined with thread 1; returned value was HOLA
           Joined with thread 2; returned value was SALUT
           Joined with thread 3; returned value was SERVUS

       Lors  de  l'exécution  suivante,  le programme définit explicitement une taille de pile de
       1 Mo (avec pthread_attr_setstacksize(3)) pour les threads créés :

           $ ./a.out -s 0x100000 hola salut servus
           Thread 1: top of stack near 0xb7d723b8; argv_string=hola
           Thread 2: top of stack near 0xb7c713b8; argv_string=salut
           Thread 3: top of stack near 0xb7b703b8; argv_string=servus
           Joined with thread 1; returned value was HOLA
           Joined with thread 2; returned value was SALUT
           Joined with thread 3; returned value was SERVUS

   Source du programme

       #include <ctype.h>
       #include <errno.h>
       #include <pthread.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <unistd.h>

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

       #define handle_error(msg) \
               do { perror(msg); exit(EXIT_FAILURE); } while (0)

       struct thread_info {    /* Utilisé comme argument pour thread_start() */
           pthread_t thread_id;        /* Identifiant renvoyé par pthread_create() */
           int       thread_num;       /* N° de thread défini par l'application */
           char     *argv_string;      /* À partir de l'argument en ligne de commande */
       };

       /* Fonction de démarrage du thread : affiche l'adresse vers le haut de la pile,
          et renvoie une copie en majuscule de argv_string. */

       static void *
       thread_start(void *arg)
       {
           struct thread_info *tinfo = arg;
           char *uargv;

           printf("Thread %d : sommet de la pile près de %p; argv_string=%s\n",
                  tinfo->thread_num, (void *) &tinfo, tinfo->argv_string);

           uargv = strdup(tinfo->argv_string);
           if (uargv == NULL)
               handle_error("strdup");

           for (char *p = uargv; *p != '\0'; p++)
               *p = toupper(*p);

           return uargv;
       }

       int
       main(int argc, char *argv[])
       {
           int                 s, opt;
           void                *res;
           size_t              num_threads;
           ssize_t             stack_size;
           pthread_attr_t      attr;
           struct thread_info  *tinfo;

           /* L'option "-s" spécifie une taille de pile pour les threads. */

           stack_size = -1;
           while ((opt = getopt(argc, argv, "s:")) != -1) {
               switch (opt) {
               case 's':
                   stack_size = strtoul(optarg, NULL, 0);
                   break;

               default:
                   fprintf(stderr, "Usage: %s [-s stack-size] arg...\n",
                           argv[0]);
                   exit(EXIT_FAILURE);
               }
           }

           num_threads = argc - optind;

           /* Initialiser les attributs de création de thread. */

           s = pthread_attr_init(&attr);
           if (s != 0)
               handle_error_en(s, "pthread_attr_init");

           if (stack_size > 0) {
               s = pthread_attr_setstacksize(&attr, stack_size);
               if (s != 0)
                   handle_error_en(s, "pthread_attr_setstacksize");
           }

           /* Allouer la mémoire pour les arguments de pthread_create(). */

           tinfo = calloc(num_threads, sizeof(*tinfo));
           if (tinfo == NULL)
               handle_error("calloc");

           /* Créer un thread pour chaque argument en ligne de commande. */

           for (size_t tnum = 0; tnum < num_threads; tnum++) {
               tinfo[tnum].thread_num = tnum + 1;
               tinfo[tnum].argv_string = argv[optind + tnum];

               /* L'appel pthread_create() stocke l'identifiant du thread dans
                  l'élément correspondant de tinfo[]. */

               s = pthread_create(&tinfo[tnum].thread_id, &attr,
                                  &thread_start, &tinfo[tnum]);
               if (s != 0)
                   handle_error_en(s, "pthread_create");
           }

           /* Détruire l'objet des attributs du thread dans la mesure où
              il n'est plus nécessaire. */

           s = pthread_attr_destroy(&attr);
           if (s != 0)
               handle_error_en(s, "pthread_attr_destroy");

           /* Maintenant joindre chaque thread et afficher la valeur qu'il renvoie. */

           for (size_t tnum = 0; tnum < num_threads; tnum++) {
               s = pthread_join(tinfo[tnum].thread_id, &res);
               if (s != 0)
                   handle_error_en(s, "pthread_join");

               printf("Thread joint %d ; la valeur renvoyée est %s\n",
                       tinfo[tnum].thread_num, (char *) res);
               free(res);      /* Libérer la mémoire allouée par thread */
           }

           free(tinfo);
           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       getrlimit(2), pthread_attr_init(3), pthread_cancel(3), pthread_detach(3),
       pthread_equal(3), pthread_exit(3), pthread_getattr_np(3), pthread_join(3),
       pthread_self(3), pthread_setattr_default_np(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>, Frédéric Hantrais
       <fhantrais@gmail.com> et Jean-Pierre Giraud <jean-pierregiraud@neuf.fr>

       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⟩.