I.            Introduction

Dans ce chapitre, nous voulons présenter le problème des attentes actives sur plusieurs descripteurs.

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 (les informations de contrôle des sockets).

La manière traditionnelle de construire une application serveur réseau est de constuire un bloc principal attendant une connexion par la primitive accept. Dès qu’une demande de connexion survient, on crée un processus fils par fork : le fils prend en charge la communication et le père se remet en position d’attente d’une nouvelle connexion.

Le multiplexage permet au contraire de construire un serveur autour d’un seul processus qui multiplexe les demandes de connexion et qui les prend en charge aussi bien qu’il le peut.

Cette fonction permet à un processus d’informer le noyau de surveiller des descripteurs en attente d’événements, et de réveiller le processus si un ou des événements se sont produits.

 

But : Comment faire si on a plusieurs connexions à gérer en même temps ?

Solution : les outils de sélection.

 

II.    Les outils de sélection

II.1. la primitive select

L’avantage de l’utilisation de select est que le serveur n’est qu’un seul processus, il n’y a donc pas besoin de primitives de synchronisations ou de communication entre processus.

 

1.    Syntaxe  

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

·       nfds : égal au plus grand descripteur de tous les ensembles + 1 (et non au nombre total de descripteurs, en gros on prend le dernier créé + 1).

·       rdfds : pointeur vers l’ensemble de descripteurs à examiner en lecture (NULL est l’ensemble vide).

·       wrfds : pointeur vers l’ensemble de descripteurs à examiner en écriture (NULL est l’ensemble vide).

·       exfds :  pointeur vers l’ensemble de descripteurs à examiner un état exceptionnel, par exemple les messages urgents (NULL est l’ensemble vide).

·       timeout: pointeur vers une structure timeval donnant le delai d’attente maximum. Mettre NULL pour un temps infini.

 

Le type fd_set est décrit dans <sys/types.h>,

Le prototype de select est dans <sys/time.h>.

struct timeval {

long tv sec ; /* secondes */

long tv use ; /* microsecondes */

}

 

2.    Valeur renvoyée :

Au retour, la primitive précise quels sont les descripteurs qui sont actifs dans les champs readfs, writefs et exceptfs.

L’appel à select retourne -1 dans cas d’echec, et le nombre de descripteurs prêts dans les autres cas. Les descripteurs prêts sont alors positionnés dans les trois ensembles

 

 

3.    Fonctions associées aux descripteurs

<sys/types.h>,

FD_ZERO(fd_set * set) : vider l'ensemble

FD_SET(int fd,fd_set * set) : ajouter fd

FD_CLR(int fd,fd_set * set) : retirer fd

FD_ISSET(int fd,fd_set * set) : tester la pr_esence de fd

Fd_set rset;

FD_ZERO(&rset); //initialization à 0 de rset

FD_SET(1, &rset); //Les descripteur 1, 6 et 7 sont mis dans rset

FD_SET(6, &rset);

 

4.    Principe de fonctionnement  (Mise en  œuvre)

 

·       Initialiser les ensembles de descripteurs avec FD_ZERO

·       Insérer les descripteurs avec FD_SET selon l'opération souhaitée

1.   Lecture : read(), recv(), recvfrom() ou accept()

2.   Ecriture : write() ou send()

3.   ….

·       Faire un calcul de max. pour déterminer le plus grand descripteur

·       Préparer éventuellement un timeout

·       Effectuer l'appel à select

·       Pour chaque descripteur précédemment inséré

1.   Tester avec FD_ISSET s'il est toujours présent dans son ensemble

2.   Si oui : faire l'opération souhaitée (correspondant à l'ensemble)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Modifié le: mercredi 8 mai 2024, 22:14