pthread_create

PTHREAD_CREATE(3)          Manuel du programmeur Linux         PTHREAD_CREATE(3)



NOM
       pthread_create - Créer un nouveau thread

SYNOPSIS
       #include <pthread.h>

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

       Compiler et éditer les liens avec -pthreads.

DESCRIPTION
       La fonction pthread_create()  démarre un nouveau thread 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 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(). Cela entraine 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 revenir, 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)).

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 processus léger.

       EAGAIN A system-imposed limit on the number of threads was encountered.
              There are a number of limits that may trigger this error: the
              RLIMIT_NPROC soft resource limit (set via setrlimit(2)), which
              limits the number of processes and threads for a real user ID, was
              reached; the kernel's system-wide limit on the number of processes
              and threads, /proc/sys/kernel/threads-max, was reached (see
              proc(5)); or the maximum number of PIDs, /proc/sys/kernel/pid_max,
              was reached (see 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).

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

CONFORMITÉ
       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 démons qui ne se préoccupent pas de la valeur de sortie
       de ses threads. 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é.

       Under the NPTL threading implementation, if the RLIMIT_STACK soft
       resource limit at the time the program started has any value other than
       "unlimited", then it determines the default stack size of new threads.
       Using pthread_attr_setstacksize(3), the stack size attribute can be
       explicitly set in the attr argument used to create a thread, in order to
       obtain a stack size other than the default.  If the RLIMIT_STACK resource
       limit is set to "unlimited", a per-architecture value is used for the
       stack size.  Here is the value for a few architectures:

              ┌─────────────┬────────────────────┐
              │Architecture Default stack size │
              ├─────────────┼────────────────────┤
              │i386         │               2 MB │
              ├─────────────┼────────────────────┤
              │IA-64        │              32 MB │
              ├─────────────┼────────────────────┤
              │PowerPC      │               4 MB │
              ├─────────────┼────────────────────┤
              │S/390        │               2 MB │
              ├─────────────┼────────────────────┤
              │Sparc-32     │               2 MB │
              ├─────────────┼────────────────────┤
              │Sparc-64     │               4 MB │
              ├─────────────┼────────────────────┤
              │x86_64       │               2 MB │
              └─────────────┴────────────────────┘
BOGUES
       Dans l'implémentation obsolète LinuxThreads, chacun des threads dans un
       processus a un identifiant de processus différent. Ceci est en violation
       des spécifications POSIX sur les threads, et est la cause de beaucoup de
       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

       In the next run, the program explicitly sets a stack size of 1 MB (using
       pthread_attr_setstacksize(3))  for the created threads:

           $ ./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 <pthread.h>
       #include <string.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <errno.h>
       #include <ctype.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, *p;

           printf("Thread %d: top of stack near %p; argv_string=%s\n",
                   tinfo->thread_num, &p, tinfo->argv_string);

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

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

           return uargv;
       }

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

           /* 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(struct thread_info));
           if (tinfo == NULL)
               handle_error("calloc");

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

           for (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 (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)

COLOPHON
       Cette page fait partie de la publication 5.08 du projet man-pages Linux.
       Une description du projet et des instructions pour signaler des anomalies
       et la dernière version de cette page, peuvent être trouvées à l'adresse
       https://www.kernel.org/doc/man-pages/.


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



Linux                              9 juin 2020                 PTHREAD_CREATE(3)