Provided by: manpages-fr-dev_4.26.0-1_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-2008.

HISTORIQUE

       POSIX.1-2001.

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 : 2 Mo pour la plupart des architectures ;  4  Mo  pour  POWER  et
       Sparc-64.

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 <sys/types.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 {    /* Used as argument to thread_start() */
           pthread_t thread_id;        /* ID returned by pthread_create() */
           int       thread_num;       /* Application-defined thread # */
           char     *argv_string;      /* From command-line argument */
       };

       /* Thread start function: display address near top of our stack,
          and return upper-cased copy of argv_string. */

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

           printf("Thread %d: top of stack near %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;

           /* The "-s" option specifies a stack size for our 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;

           /* Initialize thread creation attributes. */

           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");
           }

           /* Allocate memory for pthread_create() arguments. */

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

           /* Create one thread for each command-line argument. */

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

               /* The pthread_create() call stores the thread ID into
                  corresponding element of tinfo[]. */

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

           /* Destroy the thread attributes object, since it is no
              longer needed. */

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

           /* Now join with each thread, and display its returned value. */

           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("Joined with thread %d; returned value was %s\n",
                      tinfo[tnum].thread_num, (char *) res);
               free(res);      /* Free memory allocated by 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 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.

Pages du manuel de Linux 6.9.1                    15 juin 2024                                 pthread_create(3)