.\" -*- coding: UTF-8 -*- .\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk .\" .\" .\" %%%LICENSE_START(VERBATIM) .\" Permission is granted to make and distribute verbatim copies of this .\" manual provided the copyright notice and this permission notice are .\" preserved on all copies. .\" .\" Permission is granted to copy and distribute modified versions of this .\" manual under the conditions for verbatim copying, provided that the .\" entire resulting derived work is distributed under the terms of a .\" permission notice identical to this one. .\" .\" Since the Linux kernel and libraries are constantly changing, this .\" manual page may be incorrect or out-of-date. The author(s) assume no .\" responsibility for errors or omissions, or for damages resulting from .\" the use of the information contained herein. The author(s) may not .\" have taken the same level of care in the production of this manual, .\" which is licensed free of charge, as they might when working .\" professionally. .\" .\" Formatted or processed versions of this manual, if unaccompanied by .\" the source, must acknowledge the copyright and authors of this work. .\" %%%LICENSE_END .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH PTHREAD_CREATE 3 "1 novembre 2020" Linux "Manuel du programmeur Linux" .SH NOM pthread_create \- Créer un nouveau thread .SH SYNOPSIS .nf \fB#include \fP .PP \fBint pthread_create(pthread_t *\fP\fIthread\fP\fB, const pthread_attr_t *\fP\fIattr\fP\fB,\fP \fB void *(*\fP\fIstart_routine\fP\fB) (void *), void *\fP\fIarg\fP\fB);\fP .fi .PP Compiler et éditer les liens avec \fI\-pthreads\fP. .SH DESCRIPTION La fonction \fBpthread_create\fP() démarre un nouveau thread dans le processus appelant. Le nouveau thread commence par appeler \fIstart_routine\fP()\ ; \fIarg\fP est passé comme unique argument de \fIstart_routine\fP(). .PP Le nouveau thread se termine d'une des manières suivantes\ : .IP * 2 Il appelle \fBpthread_exit\fP(3), en indiquant une valeur de sortie qui sera disponible pour pour un autre thread du même processus qui appelle \fBpthread_join\fP(3). .IP * Il sort de la routine \fIstart_routine\fP(). C'est équivalent à appeler \fBpthread_exit\fP(3) avec la valeur fournie à l'instruction \fIreturn\fP. .IP * Il est annulé (voir \fBpthread_cancel\fP(3)). .IP * Un des threads du processus appelle \fBexit\fP(3), ou le thread principal sort de la routine \fImain\fP(). Cela entraine l'arrêt de tous les threads du processus. .PP L'argument \fIattr\fP pointe sur une structure \fIpthread_attr_t\fP 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 \fBpthread_attr_init\fP(3) et les fonctions similaires. Si \fIattr\fP est NULL, alors le thread est créé avec les attributs par défaut. .PP Avant de revenir, un appel réussi à \fBpthread_create\fP() stocke l'identifiant du nouveau thread dans le tampon pointé par \fIthread\fP. Cet identifiant est utilisé pour se référer à ce thread dans les appels ultérieurs aux autres fonctions de pthreads. .PP Le nouveau thread hérite d'une copie du masque de signal du thread créateur (\fBpthread_sigmask\fP(3)). L'ensemble des signaux en attente pour le nouveau thread est vide (\fBsigpending\fP(2)). Le nouveau thread n'hérite pas de la pile spécifique de signaux (\fBsigaltstack\fP(2)) du thread appelant. .PP Le nouveau thread hérite de l'environnement en virgule flottante (\fBfenv\fP(3)) du thread appelant. .PP .\" CLOCK_THREAD_CPUTIME_ID in clock_gettime(2) La valeur initiale de l'horloge CPU du nouveau thread est 0 (voir \fBpthread_getcpuclockid\fP(3)). .SS "Détails spécifiques à Linux" Le nouveau thread hérite de copies des ensembles des capacités (voir \fBcapabilities\fP(7)) et des masques d'affinité CPU (consultez \fBsched_setaffinity\fP(2)). .SH "VALEUR RENVOYÉE" En cas de réussite, \fBpthread_create\fP() renvoie 0\ ; en cas d'erreur, elle renvoie un numéro d'erreur, et le contenu de \fI*thread\fP est indéfini. .SH ERREURS .TP \fBEAGAIN\fP Ressources insuffisantes pour créer un nouveau processus léger. .TP \fBEAGAIN\fP .\" NOTE! The following should match the description in fork(2) A system\-imposed limit on the number of threads was encountered. There are a number of limits that may trigger this error: the \fBRLIMIT_NPROC\fP soft resource limit (set via \fBsetrlimit\fP(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, \fI/proc/sys/kernel/threads\-max\fP, was reached (see \fBproc\fP(5)); or the maximum number of PIDs, \fI/proc/sys/kernel/pid_max\fP, was reached (see \fBproc\fP(5)). .TP \fBEINVAL\fP Paramètres incorrects dans \fIattr\fP. .TP .\" FIXME . Test the following \fBEPERM\fP Permissions insuffisantes pour définir la politique d'ordonnancement et les paramètres spécifiés dans \fIattr\fP. .SH ATTRIBUTS Pour une explication des termes utilisés dans cette section, consulter \fBattributes\fP(7). .TS allbox; lb lb lb l l l. Interface Attribut Valeur T{ \fBpthread_create\fP() T} Sécurité des threads MT\-Safe .TE .sp 1 .SH CONFORMITÉ POSIX.1\-2001, POSIX.1\-2008. .SH NOTES Consultez \fBpthread_self\fP(3) pour des informations plus détaillées sur l'identifiant de thread renvoyé dans \fI*thread\fP par \fBpthread_create\fP(). Sauf si une politique d'ordonnancement temps\-réel est employée, après un appel à \fBpthread_create\fP(), on ne sait pas quel thread \(em l'appelant ou le nouveau thread \(em sera exécuté ensuite. .PP Un thread peut être dans un état soit joignable (\fIjoinable\fP), soit détaché (\fIdetached\fP). Si un thread est joignable, un autre thread peut appeler \fBpthread_join\fP(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'\fIattr\fP n'ait été modifié (avec \fBpthread_attr_setdetachstate\fP(3)) pour créer le thread dans un état détaché. .PP Under the NPTL threading implementation, if the \fBRLIMIT_STACK\fP soft resource limit \fIat the time the program started\fP has any value other than "unlimited", then it determines the default stack size of new threads. Using \fBpthread_attr_setstacksize\fP(3), the stack size attribute can be explicitly set in the \fIattr\fP argument used to create a thread, in order to obtain a stack size other than the default. If the \fBRLIMIT_STACK\fP resource limit is set to "unlimited", a per\-architecture value is used for the stack size. Here is the value for a few architectures: .RS .TS allbox; lb lb l r. 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 .TE .RE .SH 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 \fBpthreads\fP(7). .SH EXEMPLES Le programme ci\-dessous montre l'utilisation de \fBpthread_create\fP(), ainsi qu'un certain nombre d'autres fonctions de l'API pthreads. .PP 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)\ : .PP .in +4n .EX $\fB ulimit \-s\fP 8192 # The stack size limit is 8 MB (0x800000 bytes) $\fB ./a.out hola salut servus\fP 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 .EE .in .PP In the next run, the program explicitly sets a stack size of 1\ MB (using \fBpthread_attr_setstacksize\fP(3)) for the created threads: .PP .in +4n .EX $\fB ./a.out \-s 0x100000 hola salut servus\fP 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 .EE .in .SS "Source du programme" \& .EX #include #include #include #include #include #include #include #define handle_error_en(en, msg) \e do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) #define handle_error(msg) \e 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\en", tinfo\->thread_num, &p, tinfo\->argv_string); uargv = strdup(tinfo\->argv_string); if (uargv == NULL) handle_error("strdup"); for (char *p = uargv; *p != \(aq\e0\(aq; p++) *p = toupper(*p); return uargv; } int main(int argc, char *argv[]) { int s, opt, num_threads; pthread_attr_t attr; size_t 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 \(aqs\(aq: stack_size = strtoul(optarg, NULL, 0); break; default: fprintf(stderr, "Usage: %s [\-s stack\-size] arg...\en", 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 */ struct thread_info *tinfo = calloc(num_threads, sizeof(*tinfo)); if (tinfo == NULL) handle_error("calloc"); /* Create one thread for each command\-line argument */ for (int 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 (int 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\en", tinfo[tnum].thread_num, (char *) res); free(res); /* Free memory allocated by thread */ } free(tinfo); exit(EXIT_SUCCESS); } .EE .SH "VOIR AUSSI" .ad l .nh \fBgetrlimit\fP(2), \fBpthread_attr_init\fP(3), \fBpthread_cancel\fP(3), \fBpthread_detach\fP(3), \fBpthread_equal\fP(3), \fBpthread_exit\fP(3), \fBpthread_getattr_np\fP(3), \fBpthread_join\fP(3), \fBpthread_self\fP(3), \fBpthread_setattr_default_np\fP(3), \fBpthreads\fP(7) .SH COLOPHON Cette page fait partie de la publication\ 5.10 du projet \fIman\-pages\fP 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/. .PP .SH TRADUCTION La traduction française de cette page de manuel a été créée par Christophe Blaess , Stéphan Rafin , Thierry Vignaud , François Micaux, Alain Portal , Jean-Philippe Guérard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas François , Florentin Duneau , Simon Paillard , Denis Barbier , David Prévot et Frédéric Hantrais . .PP Cette traduction est une documentation libre ; veuillez vous reporter à la .UR https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License version 3 .UE concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE. .PP Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à .MT debian-l10n-french@lists.debian.org .ME .