pthreads(7) Miscellaneous Information Manual pthreads(7)
NOM
pthreads - Threads POSIX
DESCRIPTION
POSIX.1 decrit une serie d'interfaces (fonctions et fichiers
d'en-tetes) pour la programmation multithread, couramment appelee
threads POSIX, ou pthreads. Un unique processus peut contenir plusieurs
threads, qui executent tous le meme programme. Ces threads partagent la
meme memoire globale (segments de donnees et tas), mais chaque thread a
sa propre pile (variables automatiques).
POSIX.1 requiert aussi que les threads partagent une serie d'autres
attributs (ces attributs sont par processus, plutot que par thread) :
- identifiant de processus (PID)
- identifiant de processus parent (PPID)
- identifiant de groupe de processus (PGID) et identifiant de session
(SID)
- terminal de controle
- identifiants d'utilisateur et de groupe
- descripteurs de fichier ouverts
- verrouillages d'enregistrements (consultez fcntl(2))
- gestion de signaux
- masque de creation de mode de fichier (umask(2))
- repertoire de travail (chdir(2)) et repertoire racine (chroot(2))
- temporisations d'intervalle (setitimer(2)) et temporisations POSIX
(timer_create(2))
- valeur de politesse (setpriority(2))
- limites de ressources (setrlimit(2))
- mesures de consommation de temps CPU (times(2)) et de ressources
(getrusage(2))
En plus de la pile, POSIX.1 indique que plusieurs autres attributs sont
distincts pour chaque thread, dont les suivants :
- identifiant de thread (le type de donnee pthread_t)
- masque de signaux (pthread_sigmask(3))
- la variable errno
- pile de signaux specifique (sigaltstack(2))
- politique et priorite d'ordonnancement temps reel (sched(7))
Les caracteristiques specifiques a Linux suivantes sont egalement
distinctes pour chaque thread :
- capacites (consultez capabilities(7))
- affinite CPU (sched_setaffinity(2))
Valeurs de retour des fonctions pthreads
La plupart des fonctions pthreads renvoient >0 en cas de succes et un
numero d'erreur en cas d'echec. Les numeros d'erreur pouvant etre
renvoyes ont la meme signification que ceux renvoyes dans errno par les
appels systeme conventionnels et les fonctions de la bibliotheque C.
Notez que les fonctions pthreads ne positionnent pas errno. Pour
chacune des fonctions pthreads qui peuvent produire une erreur,
POSIX.1-2001 specifie que la fonction ne peut pas echouer avec l'erreur
EINTR.
Identifiants de thread
Chacun des threads d'un processus a un unique identifiant de thread
(stocke dans le type pthread_t). Cet identifiant est renvoye a
l'appelant de pthread_create(3) et un thread peut obtenir son propre
identifiant de thread en utilisant pthread_self(3).
Les identifiants de threads ne sont garantis d'etre uniques qu'a
l'interieur d'un processus. Dans toutes les fonctions pthreads qui
acceptent un identifiant de thread comme argument, par definition, cet
identifiant fait reference a un thread dans le meme processus que celui
de l'appelant.
Le systeme peut reutiliser un identifiant de thread apres qu'un thread
qui s'est termine a ete rejoint ou qu'un thread detache se soit
termine. POSIX precise : << Si une application essaie d'utiliser un
identifiant de thread dont la duree de vie est depassee, le
comportement est indefini. >>.
Fonctions sures du point de vue des threads
Une fonction sure du point de vue des threads est une fonction qui peut
etre appelee en toute surete (c'est-a-dire qu'elle renverra le meme
resultat d'ou qu'elle soit appelee) par plusieurs threads en meme
temps.
POSIX.1-2001 et POSIX.1-2008 exigent que toutes les fonctions indiquees
dans la norme soient sures du point de vue des threads, exceptees les
fonctions suivantes :
asctime()
basename()
catgets()
crypt()
ctermid() avec un parametre non NULL
ctime()
dbm_clearerr()
dbm_close()
dbm_delete()
dbm_error()
dbm_fetch()
dbm_firstkey()
dbm_nextkey()
dbm_open()
dbm_store()
dirname()
dlerror()
drand48()
ecvt() [POSIX.1-2001 uniquement (fonction supprimee dans POSIX.1-2008)]
encrypt()
endgrent()
endpwent()
endutxent()
fcvt() [POSIX.1-2001 uniquement (fonction supprimee dans POSIX.1-2008)]
ftw()
gcvt() [POSIX.1-2001 uniquement (fonction supprimee dans POSIX.1-2008)]
getc_unlocked()
getchar_unlocked()
getdate()
getenv()
getgrent()
getgrgid()
getgrnam()
gethostbyaddr() [POSIX.1-2001 uniquement (fonction supprimee dans
POSIX.1-2008)]
gethostbyname() [POSIX.1-2001 uniquement (fonction supprimee dans
POSIX.1-2008)]
gethostent()
getlogin()
getnetbyaddr()
getnetbyname()
getnetent()
getopt()
getprotobyname()
getprotobynumber()
getprotoent()
getpwent()
getpwnam()
getpwuid()
getservbyname()
getservbyport()
getservent()
getutxent()
getutxid()
getutxline()
gmtime()
hcreate()
hdestroy()
hsearch()
inet_ntoa()
l64a()
lgamma()
lgammaf()
lgammal()
localeconv()
localtime()
lrand48()
mrand48()
nftw()
nl_langinfo()
ptsname()
putc_unlocked()
putchar_unlocked()
putenv()
pututxline()
rand()
readdir()
setenv()
setgrent()
setkey()
setpwent()
setutxent()
strerror()
strsignal() [Ajoutee dans POSIX.1-2008]
strtok()
system() [Ajoutee dans POSIX.1-2008]
tmpnam() avec un parametre non NULL
ttyname()
unsetenv()
wcrtomb() si son dernier parametre est NULL
wcsrtombs() si son dernier parametre est NULL
wcstombs()
wctomb()
Fonctions pour annulations sures asynchrones
Une fonction pour annulations sures asynchrones peut etre appelee sans
risque dans une application ou l'annulation asynchrone est activee
(consultez pthread_setcancelstate(3)).
POSIX.1-2001 et POSIX.1-2008 exigent que seules les fonctions suivantes
soient pour annulations sures asynchrones :
pthread_cancel()
pthread_setcancelstate()
pthread_setcanceltype()
Points d'annulation
POSIX.1 specifie que certaines fonctions doivent, et certaines autres
fonctions peuvent, etre des points d'annulation. Si un thread est
annulable, que son type d'annulation est differe (<< deferred >>) et
qu'une demande d'annulation est en cours pour ce thread, alors le
thread est annule quand il appelle une fonction qui est un point
d'annulation.
POSIX.1-2001 et/ou POSIX.1-2008 exigent que les fonctions suivantes
soient des points d'annulation :
accept()
aio_suspend()
clock_nanosleep()
close()
connect()
creat()
fcntl() F_SETLKW
fdatasync()
fsync()
getmsg()
getpmsg()
lockf() F_LOCK
mq_receive()
mq_send()
mq_timedreceive()
mq_timedsend()
msgrcv()
msgsnd()
msync()
nanosleep()
open()
openat() [Ajoutee dans POSIX.1-2008]
pause()
poll()
pread()
pselect()
pthread_cond_timedwait()
pthread_cond_wait()
pthread_join()
pthread_testcancel()
putmsg()
putpmsg()
pwrite()
read()
readv()
recv()
recvfrom()
recvmsg()
select()
sem_timedwait()
sem_wait()
send()
sendmsg()
sendto()
sigpause() [POSIX.1-2001 seulement (deplacee dans la liste << may >> dans
POSIX.1-2008)]
sigsuspend()
sigtimedwait()
sigwait()
sigwaitinfo()
sleep()
system()
tcdrain()
usleep() [POSIX.1-2001 seulement(fonction retiree dans POSIX.1-2008)]
wait()
waitid()
waitpid()
write()
writev()
POSIX.1-2001 et/ou POSIX.1-2008 indiquent que les fonctions suivantes
peuvent etre des points d'annulation :
access()
asctime()
asctime_r()
catclose()
catgets()
catopen()
chmod() [Ajoutee dans POSIX.1-2008]
chown() [Ajoutee dans POSIX.1-2008]
closedir()
closelog()
ctermid()
ctime()
ctime_r()
dbm_close()
dbm_delete()
dbm_fetch()
dbm_nextkey()
dbm_open()
dbm_store()
dlclose()
dlopen()
dprintf() [Ajoutee dans POSIX.1-2008]
endgrent()
endhostent()
endnetent()
endprotoent()
endpwent()
endservent()
endutxent()
faccessat() [Ajoutee dans POSIX.1-2008]
fchmod() [Ajoutee dans POSIX.1-2008]
fchmodat() [Ajoutee dans POSIX.1-2008]
fchown() [Ajoutee dans POSIX.1-2008]
fchownat() [Ajoutee dans POSIX.1-2008]
fclose()
fcntl() (pour n'importe quelle valeur de l'argument de commande)
fflush()
fgetc()
fgetpos()
fgets()
fgetwc()
fgetws()
fmtmsg()
fopen()
fpathconf()
fprintf()
fputc()
fputs()
fputwc()
fputws()
fread()
freopen()
fscanf()
fseek()
fseeko()
fsetpos()
fstat()
fstatat() [Ajoutee dans POSIX.1-2008]
ftell()
ftello()
ftw()
futimens() [Ajoutee dans POSIX.1-2008]
fwprintf()
fwrite()
fwscanf()
getaddrinfo()
getc()
getc_unlocked()
getchar()
getchar_unlocked()
getcwd()
getdate()
getdelim() [Ajoutee dans POSIX.1-2008]
getgrent()
getgrgid()
getgrgid_r()
getgrnam()
getgrnam_r()
gethostbyaddr() [POSIX.1-2001 seulement (fonction retiree dans
POSIX.1-2008)]
gethostbyname() [POSIX.1-2001 seulement (fonction retiree dans
POSIX.1-2008)]
gethostent()
gethostid()
gethostname()
getline() [Ajoutee dans POSIX.1-2008]
getlogin()
getlogin_r()
getnameinfo()
getnetbyaddr()
getnetbyname()
getnetent()
getopt() (si opterr est different de zero)
getprotobyname()
getprotobynumber()
getprotoent()
getpwent()
getpwnam()
getpwnam_r()
getpwuid()
getpwuid_r()
gets()
getservbyname()
getservbyport()
getservent()
getutxent()
getutxid()
getutxline()
getwc()
getwchar()
getwd() [POSIX.1-2001 seulement (fonction retiree dans POSIX.1-2008)]
glob()
iconv_close()
iconv_open()
ioctl()
link()
linkat() [Ajoutee dans POSIX.1-2008]
lio_listio() [Ajoutee dans POSIX.1-2008]
localtime()
localtime_r()
lockf() [Ajoutee dans POSIX.1-2008]
lseek()
lstat()
mkdir() [Ajoutee dans POSIX.1-2008]
mkdirat() [Ajoutee dans POSIX.1-2008]
mkdtemp() [Ajoutee dans POSIX.1-2008]
mkfifo() [Ajoutee dans POSIX.1-2008]
mkfifoat() [Ajoutee dans POSIX.1-2008]
mknod() [Ajoutee dans POSIX.1-2008]
mknodat() [Ajoutee dans POSIX.1-2008]
mkstemp()
mktime()
nftw()
opendir()
openlog()
pathconf()
pclose()
perror()
popen()
posix_fadvise()
posix_fallocate()
posix_madvise()
posix_openpt()
posix_spawn()
posix_spawnp()
posix_trace_clear()
posix_trace_close()
posix_trace_create()
posix_trace_create_withlog()
posix_trace_eventtypelist_getnext_id()
posix_trace_eventtypelist_rewind()
posix_trace_flush()
posix_trace_get_attr()
posix_trace_get_filter()
posix_trace_get_status()
posix_trace_getnext_event()
posix_trace_open()
posix_trace_rewind()
posix_trace_set_filter()
posix_trace_shutdown()
posix_trace_timedgetnext_event()
posix_typed_mem_open()
printf()
psiginfo() [Ajoutee dans POSIX.1-2008]
psignal() [Ajoutee dans POSIX.1-2008]
pthread_rwlock_rdlock()
pthread_rwlock_timedrdlock()
pthread_rwlock_timedwrlock()
pthread_rwlock_wrlock()
putc()
putc_unlocked()
putchar()
putchar_unlocked()
puts()
pututxline()
putwc()
putwchar()
readdir()
readdir_r()
readlink() [Ajoutee dans POSIX.1-2008]
readlinkat() [Ajoutee dans POSIX.1-2008]
remove()
rename()
renameat() [Ajoutee dans POSIX.1-2008]
rewind()
rewinddir()
scandir() [Ajoutee dans POSIX.1-2008]
scanf()
seekdir()
semop()
setgrent()
sethostent()
setnetent()
setprotoent()
setpwent()
setservent()
setutxent()
sigpause() [Ajoutee dans POSIX.1-2008]
stat()
strerror()
strerror_r()
strftime()
symlink()
symlinkat() [Ajoutee dans POSIX.1-2008]
sync()
syslog()
tmpfile()
tmpnam()
ttyname()
ttyname_r()
tzset()
ungetc()
ungetwc()
unlink()
unlinkat() [Ajoutee dans POSIX.1-2008]
utime() [Ajoutee dans POSIX.1-2008]
utimensat() [Ajoutee dans POSIX.1-2008]
utimes() [Ajoutee dans POSIX.1-2008]
vdprintf() [Ajoutee dans POSIX.1-2008]
vfprintf()
vfwprintf()
vprintf()
vwprintf()
wcsftime()
wordexp()
wprintf()
wscanf()
Une implementation peut egalement indiquer d'autres fonctions non
specifiees dans la norme comme etant des points d'annulation. En
particulier, une implementation marquera probablement toute fonction
non standard qui peut bloquer comme etant un point d'annulation (cela
inclut la plupart des fonctions qui peuvent modifier des fichiers).
Il est a remarquer que meme si une application n'utilise pas
d'annulation asynchrone, l'appel d'une fonction de la liste ci-dessus a
partir d'un gestionnaire de signal asynchrone peut provoquer
l'equivalent d'une annulation asynchrone. Le code sous-jacent de
l'utilisateur peut ne pas s'attendre a une annulation asynchrone et
l'etat des donnees de l'utilisateur peut devenir incoherent. Par
consequent, les signaux doivent etre utilises avec precaution lors de
l'entree dans une region d'annulation differee.
Compiler sous Linux
Sous Linux, les programmes utilisant l'API pthreads doivent etre
compiles avec cc -pthread.
Implementations des threads POSIX sous Linux
Deux implementations differentes des threads ont ete fournies par la
bibliotheque C de GNU sous Linux :
LinuxThreads
Il s'agit de l'implementation des Pthreads originelle. Depuis la
glibc 2.4, cette implementation n'est plus prise en charge.
NPTL (Native POSIX Threads Library)
Il s'agit de l'implementation moderne des Pthreads. Par rapport
a LinuxThreads, NPTL se conforme mieux aux exigences de la norme
POSIX.1 et fournit une meilleure performance lors de la creation
d'un grand nombre de threads. NPTL est disponible depuis la
glibc 2.3.2 et necessite des fonctionnalites presentes dans le
noyau Linux 2.6.
Ces deux implementation sont dit de type 1:1, ce qui veut dire que
chaque thread correspond a une entite d'ordonnancement du noyau. Les
deux implementations utilisent l'appel systeme clone(2) de Linux. Dans
NPTL, les primitives de synchronisation de threads (mutexes, jonction
de thread, etc.) sont implementees avec l'appel systeme futex(2) de
Linux.
LinuxThreads
Les fonctionnalites importantes de cette implementation sont les
suivantes :
- En plus du thread principal (initial) et des threads crees par le
programme avec pthread_create(3), l'implementation cree un thread de
gestion. Ce thread s'occupe de la creation et de la terminaison des
threads. Des problemes peuvent survenir si ce thread est tue de
facon imprevue.
- Les signaux sont utilises en interne par l'implementation. Sous
Linux 2.2 et suivants, les trois premiers signaux temps reel sont
utilises (voir aussi signal(7)). Sous les noyaux plus anciens,
LinuxThreads utilise SIGUSR1 et SIGUSR2. Les applications doivent
eviter d'utiliser un jeu de signaux utilise par l'implementation.
- Les threads ne partagent pas leur identifiant de processus. (En
fait, les threads LinuxThreads sont implementes comme des processus
partageant plus d'informations qu'a l'habitude, mais pas leur
identifiant de processus.) Les threads LinuxThreads (y compris le
thread de gestion) sont visibles comme des processus differents avec
ps(1).
L'implementation LinuxThreads s'ecarte de la specification POSIX.1 par
plusieurs aspects, dont les suivants :
- Les appels a getpid(2) renvoient une valeur distincte dans chaque
thread.
- Les appels a getppid(2) dans les threads autres que le thread
principal renvoient l'identifiant de processus du thread de
gestion ; a la place, getppid(2) dans ces threads renvoie la meme
valeur que getppid(2) dans le thread principal.
- Lorsqu'un thread cree un nouveau processus enfant avec fork(2),
n'importe quel thread doit pouvoir utiliser wait(2) sur l'enfant.
Cependant, l'implementation ne permet qu'au thread ayant cree
l'enfant d'appeler wait(2) sur lui.
- Lorsqu'un thread appelle execve(2), tous les autres threads sont
termines (comme le prescrit POSIX.1). Cependant, le processus
resultant a le meme PID que le thread ayant appele execve(2) : il
doit avoir le meme PID que le thread principal.
- Les threads ne partagent pas leurs identifiants d'utilisateur et de
groupe. Cela peut causer des complications pour les programmes
set-user-ID et provoquer des erreurs dans les fonctions pthreads si
une application change d'identifiant avec seteuid(2) et consorts.
- Les threads ne partagent pas l'identifiant de session et de groupe
de processus.
- Les threads ne partagent pas les verrouillages d'enregistrement
crees avec fcntl(2).
- L'information renvoyee par times(2) et getrusage(2) est par thread
au lieu d'etre par processus.
- Les threads ne partagent pas les valeurs << undo >> de semaphore
(voir semop(2)).
- Les threads ne partagent pas les temporisations d'intervalle.
- Les threads ne partagent pas leur valeur de politesse.
- POSIX.1 distingue les notions de signal envoye au processus dans son
ensemble et de signal envoye a un thread individuellement. Selon
POSIX.1, un signal envoye au processus (par exemple avec kill(2))
sera gere par un thread choisi arbitrairement au sein du processus.
LinuxThreads ne permet pas d'envoyer un signal au processus, mais
seulement a un thread specifique.
- Les threads ont des parametres de pile de signaux specifique
distincts. Cependant, les parametres de pile specifique d'un nouveau
thread sont copies a partir du thread qui l'a cree, ce qui veut dire
que les threads partagent initialement une meme pile de signaux
specifique. (Un nouveau thread devrait demarrer sans pile de signaux
specifique. Si deux threads gerent un signal sur leur pile
specifique au meme moment, des echecs imprevisibles du programme
risquent de se produire.)
NPTL
Avec NPTL, tous les threads d'un processus sont places dans le meme
groupe de threads. Tous les membres d'un groupe de threads partagent le
meme PID. NPTL n'utilise pas de thread de gestion.
NPTL utilise en interne les deux premiers signaux temps reel. Ces
signaux ne peuvent pas etre utilises dans les applications. Consulter
nptl(7) pour davantage de details.
NPTL a encore au moins une non conformite a POSIX.1 :
- Les threads ne partagent pas leur valeur de politesse.
Certaines non conformites n'apparaissent qu'avec des noyaux plus
anciens :
- l'information renvoyee par times(2) et getrusage(2) est par thread
au lieu d'etre globale au processus (corrige dans Linux 2.6.9) ;
- les threads ne partagent pas les limites de ressources (corrige dans
Linux 2.6.10) ;
- les threads ne partagent pas les temporisations d'intervalle
(corrige dans Linux 2.6.12) ;
- seul le thread principal est autorise a demarrer une nouvelle
session avec setsid(2) (corrige dans le noyau 2.6.16) ;
- seul le thread principal est autorise a rendre le processus leader
de son groupe de processus avec setpgid(2) (corrige dans le
noyau 2.6.16) ;
- Les threads ont des parametres de pile de signaux specifique
distincts. Cependant, les parametres de pile de signaux specifique
d'un nouveau thread sont copies de ceux du thread qui l'a cree, de
facon que les threads partagent initialement une pile de signaux
specifique dans Linux 2.6.16).
Veuillez noter les points suivants a propos de l'implementation NPTL :
- Si la limite souple de taille de pile (voir dans setrlimit(2) la
description de RLIMIT_STACK) est differente de unlimited, cette
valeur determine la taille de pile par defaut pour les nouveaux
threads. Pour avoir un effet, cette limite doit etre definie avant
le demarrage du programme, par exemple en utilisant la commande
ulimit -s de l'interpreteur de commandes (limit stacksize dans csh).
Determiner l'implementation des threads utilisee
Depuis glibc 2.3.2, la commande getconf(1) peut etre utilisee pour
determiner l'implementation de threads du systeme, par exemple :
bash$ getconf GNU_LIBPTHREAD_VERSION
NPTL 2.3.4
Avec des versions plus anciennes de la glibc, une commande comme la
suivante devrait etre suffisante pour determiner l'implementation de
threads par defaut :
bash$ $( ldd /bin/ls | grep libc.so | awk '{print $3}' ) | \
egrep -i 'threads|nptl'
Native POSIX Threads Library by Ulrich Drepper et al
Choisir l'implementation des threads : LD_ASSUME_KERNEL
Sur les systemes avec une glibc fournissant a la fois LinuxThreads et
NPTL (i.e. glibc 2.3.x), la variable d'environnement LD_ASSUME_KERNEL
peut etre utilisee pour ecraser le choix par defaut d'implementation de
threads fait par l'editeur de liens dynamiques. Cette variable indique
a l'editeur de liens dynamiques qu'il doit faire comme s'il etait
execute avec une version particuliere du noyau. En indiquant une
version du noyau ne fournissant pas les fonctionnalites necessitees par
NPTL, on peut forcer l'utilisation de LinuxThreads. (La raison la plus
probable pour cela est d'executer une application (boguee) qui depend
d'un comportement de LinuxThreads non conforme a la specification.) Par
exemple :
bash$ $( LD_ASSUME_KERNEL=2.2.5 ldd /bin/ls | grep libc.so | \
awk '{print $3}' ) | egrep -i 'threads|nptl'
linuxthreads-0.10 by Xavier Leroy
VOIR AUSSI
clone(2), fork(2), futex(2), gettid(2), proc(5), attributes(7),
futex(7), nptl(7), sigevent(3type), signal(7)
Diverses pages de manuel de Pthreads, par exemple : pthread_atfork(3),
pthread_attr_init(3), pthread_cancel(3), pthread_cleanup_push(3),
pthread_cond_signal(3), pthread_cond_wait(3), pthread_create(3),
pthread_detach(3), pthread_equal(3), pthread_exit(3),
pthread_key_create(3), pthread_kill(3), pthread_mutex_lock(3),
pthread_mutex_unlock(3), pthread_mutexattr_destroy(3),
pthread_mutexattr_init(3), pthread_once(3), pthread_spin_init(3),
pthread_spin_lock(3), pthread_rwlockattr_setkind_np(3),
pthread_setcancelstate(3), pthread_setcanceltype(3),
pthread_setspecific(3), pthread_sigmask(3), pthread_sigqueue(3) et
pthread_testcancel(3)
TRADUCTION
La traduction francaise de cette page de manuel a ete creee par
Christophe Blaess , Stephan Rafin
, Thierry Vignaud ,
Francois Micaux, Alain Portal , Jean-Philippe
Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas
Huriaux , Nicolas Francois
, Florentin Duneau
, Simon Paillard , Denis Barbier , David Prevot
, Frederic Hantrais et Jean-
Paul Guillonneau
Cette traduction est une documentation libre ; veuillez vous reporter a
la GNU General Public License version 3
concernant les conditions
de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE.
Si vous decouvrez un bogue dans la traduction de cette page de manuel,
veuillez envoyer un message a .
Pages du manuel de Linux 6.8 2 mai 2024 pthreads(7)