Multiplexer des entrées-sorties
Dans ce chapitre, nous voulons présenter le problème des attentes actives sur plusieurs descripteur. L'exemple le plus fréquent est celui d'un serveur web, le serveur doit gérer simultanément un très grand nombre de flux d'entrée et de flux de sortie et de flux de contrôle.
Solution avec le mode non bloquant
Il est possible d'utiliser des entrées sorties non bloquantes mais c'est loin d'être la solution optimale car notre processus va réaliser de nombreux appels système inutile d'autant plus si dans le cas d'un serveur avec des comportements de clients très aléatoires. Le coût en ressources de cette attente active est extrêmement cher, et doit être évité dans le cas d'une machine en temps partagé.
Utiliser les mécanismes asynchrones
On peut utiliser des entrées-sorties asynchrones et demander au noyau de nous prévenir par un signal qui informe de l'arrivée de données sur un descripteur. Ce signal est SIGIO, mais ce n'est valable que sur les descripteurs qui sont des périphériques. De plus ce mécanisme ne désigne pas le descripteur sur lequel s'est faite l'arrivée de caractères, d'où de nouvelles pertes de temps dûes aux appels réalisés inutilement en mode non bloquant.
Les outils de sélection
La solution la plus efficace vient de systèmes de sélection qui prend un
paramètre un ensemble de descripteurs et qui permet de tester si l'un de ses
descripteurs est près à satisfaire un appel système read
ou write
. Cet appel
est bloquant jusqu'à l'arrivée de caractères sur un des descripteurs de
l'ensemble. Ainsi il n'y a pas de consommation de ressource processus inutile,
le travail est fait à un niveau plus bas (dans le noyau) de façon plus
économique en ressources.
La primitive select
La première implémentation d'un outil de sélection sous Unix est l'appel système
select
, malheureusement sa syntaxe est devenu inadapté pour des situations où
le nombre de descripteur utilisé par le programme est très grand ce qui peut
arriver facilement avec un serveur de fichier. Nous fournissons à la primitive
select :
- Les descripteurs que nous voulons scruter (l'indice du plus grand descripteur qui nous intéresse dans la table des descripteurs du processus)
- Les conditions de réveil sur chaque descripteur (en attente de lecture, écriture, évènement)
- Combien de temps nous voulons attendre.
La fonction retourne pour chaque descripteur s'il est prêt en lecture, écriture
ou si l'évènement a eu lieu, et aussi le nombre de descripteur prêts. Cette
information nous permet ensuite d'appeler read
ou write
sur les bons
descripteurs.
La primitive poll
La primitive poll
fournit un service proche de select
avec une autre forme
d'interface. Cette interface est adaptée quand le nombre de descripteurs ouvert
par le processus est très grand mais que l'on ne s'intéresse qu'à un petit
nombre de ceux ci.