Skip to main content

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.