Provided by: manpages-fr-dev_3.27fr1.4-1_all bug

NOM

       pthread_create - Creer un nouveau thread

SYNOPSIS

       #include <pthread.h>

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

       Compilez et effectuez l'edition des liens avec l'option -pthread.

DESCRIPTION

       La  fonction  pthread_create()   demarre  un  nouveau  thread  dans  le
       processus  appelant.   Le   nouveau   thread   commence   par   appeler
       start_routine() ;    arg   est   passe   comme   unique   argument   de
       start_routine().

       Le nouveau thread se termine d'une des manieres suivantes :

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

       * Il sort de la routine start_routine().  C'est  equivalent  a  appeler
         pthread_exit(3)  avec la valeur fournie a l'instruction return.

       * Il est annule (voir  pthread_cancel(3)).

       * Un  des  threads du processus appelle exit(3), ou le thread principal
         sort de la routine main(). Cela entraine l'arret de tous les  threads
         du processus.

       L'argument attr pointe sur une structure pthread_attr_t dont le contenu
       est utilise  pendant  la  creation  des  threads  pour  determiner  les
       attributs  du  nouveau  thread.  Cette  structure  est initialisee avec
       pthread_attr_init(3) et les fonctions similaires.  Si  attr  est  NULL,
       alors le thread est cree avec les attributs par defaut.

       Avant   de   revenir,   un  appel  reussi  a  pthread_create()   stocke
       l'identifiant du nouveau thread dans le tampon pointe par  thread.  Cet
       identifiant  est  utilise  pour  se referer a ce thread dans les appels
       ulterieurs aux autres fonctions de pthreads.

       Le nouveau thread herite d'une copie du  masque  de  signal  du  thread
       createur  (pthread_sigmask(3)).  L'ensemble des signaux en attente pour
       le nouveau thread est vide (sigpending(2)). Le nouveau thread  n'herite
       pas  de  la  pile  specifique  de  signaux  (sigaltstack(2))  du thread
       appelant.

       Le nouveau  thread  herite  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'etails sp'ecifiques `a Linux
       Le nouveau thread herite de copies des ensembles  des  capacites  (voir
       capabilities(7))     et   des   masques   d'affinite   CPU   (consultez
       sched_setaffinity(2)).

VALEUR RENVOY'EE

       En cas de reussite, pthread_create() renvoie 0 ; en cas d'erreur,  elle
       renvoie un numero d'erreur, et le contenu de *thread est indefini.

ERREURS

       EAGAIN Ressources  insuffisantes  pour  creer un nouveau thread, ou une
              limite sur le nombre de threads imposee par  le  systeme  a  ete
              atteinte. Ce dernier cas peut arriver de deux facons : la limite
              souple RLIMIT_NPROC (changee par setrlimit(2)),  qui  limite  le
              nombre  de  processus  pour un identifiant d'utilisateur reel, a
              ete atteinte ; ou alors la limite imposee par le  noyau  sur  le
              nombre  total  de  threads,  /proc/sys/kernel/threads-max, a ete
              atteinte.

       EINVAL Parametres invalides dans attr.

       EPERM  Permissions   insuffisantes   pour    definir    la    politique
              d'ordonnancement et les parametres specifies dans attr.

CONFORMIT'E

       POSIX.1-2001.

NOTES

       Consultez  pthread_self(3)   pour  des informations plus detaillees sur
       l'identifiant de thread renvoye dans *thread par pthread_create(). Sauf
       si  une  politique  d'ordonnancement  temps-reel est employee, apres un
       appel a pthread_create(), on ne sait pas quel thread --  l'appelant  ou
       le nouveau thread -- sera execute ensuite.

       Un  thread  peut  etre  dans  un  etat  soit joignable (joinable), soit
       detache (detached). Si un thread est joignable, un  autre  thread  peut
       appeler  pthread_join(3)   pour  attendre  que ce thread se termine, et
       recuperer sa valeur de sortie. Ce n'est que quand un thread termine  et
       joignable a ete joint que ses ressources sont rendues au systeme. Quand
       un thread detache  se  termine,  ses  ressources  sont  automatiquement
       rendues  au  systeme ;  il  n'est pas possible de joindre un tel thread
       afin d'en obtenir la valeur de sortie. Mettre  un  thread  dans  l'etat
       detache   est  pratique  pour  certains  types  de  demons  qui  ne  se
       preoccupent pas de la valeur de sortie de ses threads. Par  defaut,  un
       nouveau  thread  est  cree dans l'etat joignable, a moins qu'attr n'ait
       ete modifie (avec pthread_attr_setdetachstate(3)) pour creer le  thread
       dans un etat detache.

       Sous  Linux/x86-32,  la  taille  de  la pile par defaut pour un nouveau
       thread est de 2 megaoctets. Avec l'implementation NPTL,  si  la  limite
       souple  RLIMIT_STACK a une valeur autre qu'<< unlimited >> au moment o`u
       le programme a d'emarr'e, alors elle determine la taille de la  pile  par
       defaut  pour  les  nouveaux  threads. Afin d'obtenir une taille de pile
       differente   de   la   valeur   par    defaut,    il    faut    appeler
       pthread_attr_setstacksize(3)  avec  la  valeur souhaitee sur l'argument
       attr utilise pour creer un thread.

EXEMPLE

       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'execution  suivante,  sur  un systeme avec l'implementation
       NPTL, la taille de la pile vaut par defaut la valeur  renvoyee  par  la
       limite de la ressource << stack size >> (taille de la pile) :

           $ ulimit -s
           8192            # The stack size limit is 8 MB (0x80000 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'execution  suivante, le programme definit explicitement une
       taille de pile de 1 Mo (avec  pthread_attr_setstacksize(3))   pour  les
       threads crees :

           $ ./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 = (struct thread_info *) 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);
       }

BOGUES

       Dans l'implementation obsolete LinuxThreads, chacun des threads dans un
       processus  a  un  identifiant  de  processus  different.  Ceci  est  en
       violation  des specifications POSIX sur les threads, et est la cause de
       beaucoup de non conformite au standard. Consultez pthreads(7).

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), pthreads(7)

COLOPHON

       Cette page fait partie de  la  publication  3.27  du  projet  man-pages
       Linux.  Une description du projet et des instructions pour signaler des
       anomalies      peuvent      etre       trouvees       a       l'adresse
       <URL:http://www.kernel.org/doc/man-pages/>.

TRADUCTION

       Depuis  2010,  cette  traduction est maintenue a l'aide de l'outil po4a
       <URL:http://po4a.alioth.debian.org/>   par   l'equipe   de   traduction
       francophone        au        sein        du       projet       perkamon
       <URL:http://perkamon.alioth.debian.org/>.

       Denis Barbier (2010).

       Veuillez  signaler  toute  erreur   de   traduction   en   ecrivant   a
       <debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
       paquet manpages-fr.

       Vous pouvez toujours avoir acces a la version anglaise de  ce  document
       en utilisant la commande << man -L C <section> <page_de_man> >>.