Man page - pthread_create(3)

Packages contains this manual

Available languages:

en fr ja ru

Manual

pthread_create

NOM
BIBLIOTHÈQUE
SYNOPSIS
DESCRIPTION
Détails spécifiques à Linux
VALEUR RENVOYÉE
ERREURS
ATTRIBUTS
STANDARDS
HISTORIQUE
NOTES
BOGUES
EXEMPLES
Source du programme
VOIR AUSSI
TRADUCTION

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

Image grohtml-3874782-1.png

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 oĂč 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 .