Les threads POSIX
La programmation par thread (activité) est naturelle pour gérer des phénomènes asynchrones. Les entrées utilisateur dans les interfaces graphiques (souris, clavier) sont plus facile à gérer si l'on peut séparer l'activité principale du logiciel de la gestion des commandes utilisateurs. Les entrées sorites multiples sont gérées plus simplement en utilisant des threads.
Les activités sont une nouvelle façon de voire les processus dans un système. L'idée est de séparer en deux le concept de processus. La première partie est l'environnement d'exécution, on y retrouve une très grande partie des éléments constitutifs d'un processus en particulier les informations sur le propriétaire, la position dans l'arborescence le masque de création de fichier etc. La deuxième partie est l'activité, c'est la partie dynamique, elle contient une pile, un context processeur (pointeur d'instruction etc), et des données d'ordonancement.
L'idée de ce découpage est de pouvoir associer plusieurs activité au même environnement d'exécution. L'organisation en mémoire pour un processus UNIX avec plusieurs threads est disponible dans la figure ci dessous
On peut grâce au thread gérer plusieurs phénomènes asynchrone dans le même contexte, c'est à dire, un espace d'adressage commun, ce qui est plus confortable que de la mémoire partagée et moins coûteux en ressource que plusieurs processus avec un segment de mémoire partagé. Un processus correspond à une instance d'un programme en cours d'exécution. Un thread correspond à l'activité d'un processeur dans le cadre d'un processus. Un thead ne peut pas exister sans processus (la tâche englobante), mais il peut y avoir plusieurs thread par processus dans le cas de linux il ne peut y avoir de tâche sans au moins une activité.
Description
Un processus est composé des parties suivantes : du code, des données, une pile, des descripteurs de fichiers, des tables de signaux. Du point de vue du noyau, transférer l'exécution à un autre processus revient à rediriger les bons pointeurs et recharger les registres du processeur de la pile. Les divers threads d'un même processus peuvent partager certaines parties : le code, les données, les descripteurs de fichiers, les tables de signaux. En fait, ils ont au minimum leur propre pile, et partagent le reste.
fork
et exec
Après un fork, le fils ne contient qu'une seule activité (celle qui a exécuté le
fork). Attention aux variables d'exclusion mutuelle (qui font parti de l'espace
d'adressage partagé) qui sont conservées après le fork()
et donc le contenu ne
varie pas. Ainsi si une activité a pris le sémaphore avant le fork()
, si
l'activité principale cherche à prendre ce sémaphore après le fork()
elle sera
indéfiniment bloquée.
Après un exec
, le processus ne contient plus que la thread qui a executé l'une
des six commandes exec
. Pas de problème avec les sémaphores comme l'espace
d'adressage a changé.
clone
Sous linux (et rarement sous les sytèmes Unix) il existe un appel système un peu
spécial. Cet appel système réalise un dédoublement de processus comme fork
d'où son nom de clone
. Cet appel système permet de préciser exactement ce que
l'on entend partager entre le processus père et le processus fils. Éléments
partageables :
- ppid Création d'un frère au lieux d'un fils
- FS Partage de la structure d'information liée au système de fichier
- FILES Partage de la table des descripteurs
- SIGHAND Partage de la table des gestionnaires de Signaux, mais pas des masques de signaux
- PTRACE Partage du crochet (hook) de debug voir l'appel ptrace
- VFORK Partage du processeur ! le processus père est bloqué tant que le
fils n'a pas exécuté soit
_exit
soitexecve
, c'est à dire qu'il s'est détaché de tout les éléments partageable du processus père (sauf lesFILEs
) - VM Partage de la mémoire virtuelle, en particulier les allocations et
désallocations par
mmap
etmunmap
sont visibles par les deux processus. - pid Les deux processus ont le même numéro
- THREAD Partage du groupe de thread, les deux processus sont ou ne sont pas dans le même groupe de threads.
Les noms de fonctions
pthread[_objet]_operation[_np]
où
- objet désigne si il est présent le type de l'objet auquel la fonction
s'applique. Les valeurs possibles de objet peuvent être
cond
pour une variable de condition etmutex
pour un sémaphore d'exclusion mutuelle - opération désigne l'opération a réaliser, par exemple
create
,exit
ouinit
.
Le suffixe np
indique, si il est présent, qu'il s'agit d'une fonction non
portable, c'est à dire Hors Norme.
Les noms de types
pthread[_objet]_t
avec objet prenant comme valeur cond, mutex ou rien pour une thread