Un processus définit l’ensemble des ressources nécessaires à l’exécution d’un programme. Plusieurs processus peuvent, comme nous l’expliquerons plus en détails au chapitre V, exécuter le même code mais ils disposent chacun d’un espace d’adressage et d’autres ressources propres nécessaires à leur exécution.
L’apparition des machines multi-processeurs, le dévelopement d’applications client-serveur dans lesquelles une machine doit répondre à de nombreuses requêtes, ont montré les limites de ce modèle. Il est difficile de faire coopérer des processus indépendants : chacun dispose de ses ressources propres indépendantes, protégées par le moniteur, contre toute tentative d'accès aux zones mémoire qui lui correspondent par les autres proicessus. Faire communiquer des processus nécessite donc de recourir à des techniques sophistiquées qui font appel à des bibliothèques spécialisées. Ceci est compliqué, couteux et consommateur de ressources.
On a donc imaginé la possibilité de découper un processus en sous processus ou threads. Tous les threads partagent le même environnement que le processus dont ils sont issus et exécutent chacun la tache pour laquelle ils ont été programmés. Les threads fils et leur père partagent toutes leurs données : modifier la valeur d'une variable dans l'un la modifie pour tous les autres. La meilleure image que l'on puisse en donner est celle de fonctions qui partageraient une zone de mémoire commune.
L'emploi des threads s'est encore accru dans les processeurs modernes multi-coeurs qui sont capables de parallèliser des séries d'instructions. Il est évident que lorsqu'on en vient à paralléliser le fonctionnement au niveau de petits groupes d'instructions que seule la notion de threads peut s'appliquer, pas celle de rpocessus coopératifs pour lesquels tout le gain obtenu par le parallèlisme serait perdu dans le changement de contexte.
On peut schématiser le partage des ressources entre processus et threads comme indiqué sur la figure 3.15.
figure 3.15 : schéma du partage des ressources entre un processus et ses threads
Parmi les données communes au processus père et à ses et aux threads, on peut citer :
- le répertoire de travail
- l’implantation en mémoire
- l’ensemble des descripteurs …
- les droits du processus et son propriétaire (ceci sera explicité au chapitre IV).
Le processus père comme chaque thread possède en propre :
- ses registres
- ses piles d’exécution
- ses signaux de communication
- l’ensemble des tables et variables nécessaires à gérer son avancement
Exemple
/* Exemple de thread sous Unix */
#include <stdio.h>
#include <pthread.h>
/*
déclaration ci-dessous pour les structures qui récupèrent les tid
La dimension 3 s'explique car on veut créer 3 threads
*/
void mon_thread(int );
pthread_t pthread_id[3];
main()
{
int i;
for (i=0;i<3;i++)
{
/*
Création de threads. Arguments :
- identification du thread : structure de type pthread_t
(3 dans et exemple)
- attributs : NULL par défaut
- pointeur sur la fonction à exécuter
- pointeurs sur la liste des arguments de la fonction
Warning à la compilation car on devrait passer un pointeur sur
l'argument de la fonction mon_thread. Mais comme chaque thread est
susceptible de modifier les arguments de la fonction à exécuter et
que leur ordre d'exécution ne peut être connu ni systématiquement
le même, on risque de se retrouver avec une variable i modifiée
aléatoirement dans un thread, et donc avec une valeur incohérente
pour les autres threads. Cela provient du fait que les threads
partagent le même espace de données. Au contraire si on passe les
arguments des fonctions par valeur chaque instance crée un espace
particulier qui évite ce phénomène.
*/
if(pthread_create(pthread_id+i, NULL,
(void *)mon_thread,i) <0)
fprintf(stderr,"Erreur création thread %d\n",i);
}
fprintf(stdout,"thread initial pid %d tid %d\n",getpid(),
pthread_self());
}
/* fonction exécutée par chaque thread
*/
void mon_thread(int i)
{
fprintf(stdout,"Thread n° %d, pid %d, tid %d\n",i, getpid(),
pthread_self());
sleep(2);
}
Copyright Yves Epelboin, université P.M. Curie 1998, MAJ
4 avril, 2005