On Sun, 5 Dec 1999, Yaneric Roussel wrote:
>
>
>
> >From: Martin Quinson <[EMAIL PROTECTED]>
> > > Ai-je bien compris? Si oui, pourquoi y-a-t-il cette diff�rence entre les
> > > threads utilisateurs et syst�mes?
> >
> >Ben la r�ponse est dans la question : c'est � l'utilisateur >d'ordonnancer
> >les threads utilisateurs. Le systeme ne sait meme pas >qu'ils existent.
> >Comment pourait il les migrer d'un processeur sur >l'autre ?
>
> Ok, d'accord, mais alors comment Linux fait-il pour savoir qu'un processus
> syst�me poss�de plusieurs threads et qu'il peut alors les partager sur plus
> d'un processeur?
>
> Si, lorsque l'on parle de processus syst�mes, on parle seulement du noyau,
> je comprends que le noyau a pu �tre b�tit pour cela, mais si �a inclu tout
> ce qui est autour, je ne voie pas pourquoi Linux pourrais prendre la
> d�cision de distribuer sur plus d'un processeur des threads provenant d'un
> processus syst�me et ne pas �tre capable de faire la m�me chose pour un
> processus utilisateur...
J'ai l'impression qu'il y a quelques confusions entre les divers noms
employ�s. Je vais essayer d'expliquer les choses comme je les comprends.
Tout d'abord, le noyau Linux.
Au niveau de l'ordonnancement (le scheduler), le noyau linux ne manipule
que des "kernel threads". Ces threads sont identifi�s dans le noyau par
une structure de donn�es du type "struct task_struct". Chaque "kernel
thread" a, en particulier, un pid qui l'identifie et permet de lui envoyer
des signaux.
Quand le shell appelle fork() pour lancer un processus standard, le
noyau va cr�er un nouveau "kernel thread". Chaque fois que le scheduler
donne la main � ce "kernel thread", cela signifie que le processus
s'ex�cute.
Le scheduler du noyau linux ordonnance les "kernel threads" sur tous les
processeurs � sa disposition. Avec un noyau standard (sans patch
particulier), un "kernel thread" peut �tre ordonnanc� (ex�cut�) sur
n'importe quel processeur disponible, et le noyau peut tr�s bien le
changer de processeur chaque fois qu'il lui donne la main.
Au niveau utilisateur.
Dans ce contexte, le mot "thread" change de sens. Il signifie alors "fil
d'ex�cution dans un processus". Un thread poss�de en propre ses registres
processeurs (PC, SP, registres de donn�es, ...). Il partage avec les
autres threads dans un processus, entre autres, la table des fichiers
ouverts et la m�moire.
On distingue plusieurs type de tels threads suivant la fa�on dont ils
sont ordonnanc�s, les deux plus importants �tant les threads utilisateurs
et les threads noyaux.
Les threads utilisateurs.
Les threads utilisateurs sont des threads g�r�s par le processus
lui-m�me (souvent � l'aide d'une biblioth�que). Le noyau n'a pas
connaissance de ces threads, il ne voit qu'une seule entit�. Pour linux,
cela signifie qu'il n'y a qu'un seul "kernel thread" qui s'occupe de tous
ces threads utilisateurs.
Avantages :
* efficacit� (il n'y a pas besoin de faire d'appels syst�mes pour les
primitives relatives aux threads (cr�ation, synchronisation), seulement
des appels de fonctions � la biblioth�que de threads utilis�e),
* flexibilit� (la biblioth�que peut g�rer ses threads comme bon lui
semble et mettre en place des comportement sp�cifiques (exemple: migration
de threads d'une machine � une autre dans PM2))
Inconv�nients :
* On ne b�n�ficie pas des SMP (le scheduler noyau n'oronnance le "kernel
thread" que sur un seul processeur � un instant donn�)
* Appels bloquants : lorsqu'un thread fait un appel bloquant (lecture
sur une socket par exemple), le noyau suspend le "kernel thread" jusqu'�
completion de l'appel syst�me, emp�chant d'autres threads utilisateurs de
s'ex�cuter, m�me s'ils sont pr�ts.
Les threads noyaux.
Dans ce cas, c'est l'OS qui mets � la disposition de l'utilisateur des
primitives pour g�rer les threads. La situation de linux est un peu
particuli�re � ce sujet.
Linux met � disposition de l'utilisateur la primitive clone(). C'est une
version plus puissante que fork() (en fait, fork() appel clone() avec les
bons flags). clone() cr�e un nouveau "kernel thread" qui peut (suivant les
flags pass�s en param�tre) partager ou non diff�rents aspects avec le
"kernel thread" faisant l'appel. Le nouveau "kernel thread" a
n�cessairement de nouveaux registres processeurs, un nouveau pid, par
contre, il peut partager ou non avec l'ancien la table de fichiers
ouverts, l'espace d'adressage (la m�moire), ...
Xavier Leroy a utiliser cet appel syst�me pour construire autour une
biblioth�que de threads noyaux : c'est la biblioth�que que l'on a
l'habitude d'utiliser sous linux (libpthread). La chose un peu �trange
sous linux, c'est que ces threads ont un pid diff�rent (alors qu'ils
devraient partager celui du processus)
Avantages :
* utilisation des SMP : chaque thread s'ex�cute dans un "kernel
thread" diff�rent qui peuvent �tre ordonnanc�s par le noyau chacun sur un
processeur diff�rent en m�me temps.
* Appels bloquant : quand un thread fait un appel bloquant, il ne bloque
que son "kernel thread", les autres threads continuent de s'ex�cuter dans
leur "kernel thread".
Inconv�nients :
* efficacit� : le passage en mode noyau (appel syst�me) pour toutes les
primitives de cr�ation/synchronisation/... est co�teux
* flexibilit� : on ne peut faire avec ce genre de threads que ce qui est
pr�vu dans le noyau.
Autres types de threads.
On trouve �galement d'autres types de biblioth�que de threads, en
particulier des biblioth�ques dites "mixte" ou "� deux niveau" o� quelques
threads noyaux ordonnancent des threads utilisateurs, ce qui permet plus
de flexibilit� tout en profitant des SMP (exemple: biblioth�que marcel de
PM2)
En esp�rant que ces pr�cisions soient utiles,
Vincent