table of contents
other sections
SELECT(2) | Manuel du programmeur Linux | SELECT(2) |
NOM¶
select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - Multiplexage d'entrées-sorties synchronesSYNOPSIS¶
/* D'après POSIX.1-2001 */#include <sys/select.h>/* D'après les standards précédents */#include <sys/time.h>#include <sys/types.h>#include <unistd.h>int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);void FD_CLR(int fd, fd_set *set);int FD_ISSET(int fd, fd_set *set);void FD_SET(int fd, fd_set *set);void FD_ZERO(fd_set *set);#include <sys/select.h>int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);
Exigences de macros de test de fonctionnalités pour la glibc (consultez feature_test_macros(7)) :
DESCRIPTION¶
select() et pselect() permettent à un programme de surveiller plusieurs descripteurs de fichier, en attendant qu'au moins l'un de ces descripteurs soit « prêt » pour une certaine classe d'opérations d'entrée-sortie. Un descripteur de fichier est considéré comme prêt s'il est possible d'effectuer l'opération correspondante (par exemple read(2)) sans bloquer. select() et pselect() ont un comportement identique, avec trois différences :- (i)
- La fonction select() utilise un délai exprimé avec une struct timeval (secondes et microsecondes), alors que pselect() utilise une struct timespec (secondes et nanosecondes).
- (ii)
- La fonction select() peut modifier le paramètre timeout pour indiquer le temps restant. La fonction pselect() ne change pas ce paramètre.
- (iii)
- La fonction select() n'a pas de paramètre sigmask et se comporte comme pselect() avec une valeur NULL pour sigmask
ready = pselect(nfds, &readfds, &writefds, &exceptfds, timeout, &sigmask);est équivalent à exécuter de façon atomique les appels suivants :
sigset_t origmask; pthread_sigmask(SIG_SETMASK, &sigmask, &origmask); ready = select(nfds, &readfds, &writefds, &exceptfds, timeout); pthread_sigmask(SIG_SETMASK, &origmask, NULL);L'idée derrière pselect() est que pour l'attente d'un événement, que ce soit un signal ou une condition sur un descripteur, un test atomique est nécessaire pour éviter les situations de concurrence. (Supposons que le gestionnaire de signaux active un drapeau global et revienne. Alors un test de ce drapeau, suivi d'un appel select() peut bloquer indéfiniment si le signal arrive juste après le test mais avant l'appel. À l'inverse, pselect() permet de bloquer le signal d'abord, traiter les signaux déjà reçus, puis invoquer pselect() avec le sigmask, désiré, en évitant la situation de blocage.)
Délai maximal¶
Les structures temporelles concernées sont définies dans <sys/time.h> comme ceci :struct timeval { long tv_sec; /* secondes */ long tv_usec; /* microsecondes */ };
struct timespec { long tv_sec; /* secondes */ long tv_nsec; /* nanosecondes */ };
VALEUR RENVOYÉE¶
En cas de réussite select() et pselect() renvoient le nombre de descripteurs dans les trois ensembles de descripteurs retournés (c'est-à-dire le nombre total de bits à 1 dans readfds, writefds, exceptfds) qui peut être nul si le délai de timeout a expiré avant que quoi que ce soit d'intéressant ne se produise. Ils retournent -1 s'ils échouent, auquel cas errno contient le code d'erreur ; les ensembles et timeout ne sont plus définis, ne vous fiez plus à leur contenu après une erreur.ERREURS¶
- EBADF
- Un descripteur de fichier invalide était dans l'un des ensembles. (Peut-être un descripteur déjà fermé, ou sur lequel une erreur s'est produite.)
- EINTR
- Un signal a été intercepté ; consultez signal(7).
- EINVAL
- nfds est négatif ou la valeur contenue dans timeout est invalide.
- ENOMEM
- Pas assez de mémoire pour le noyau.
VERSIONS¶
pselect() a été ajouté à Linux dans le noyau 2.6.16. Précédemment, pselect() était émulé dans la glibc (mais voir la section BOGUES).CONFORMITɶ
select() est conforme à POSIX.1-2001 et BSD 4.4 (la fonction select() est apparue dans BSD 4.2). Généralement portable depuis ou vers des systèmes non-BSD supportant des clones de la couche sockets BSD (y compris les variantes du System V). Néanmoins, sachez que les variantes du System V définissent une variable de timeout avant le retour alors que les variantes BSD ne le font pas. pselect() est défini dans POSIX.1g, et dans POSIX.1-2001.NOTES¶
Un ensemble fd_set est un tampon de taille fixe. Exécuter FD_CLR() ou FD_SET() avec fd négatif ou supérieur ou égal à FD_SETSIZE résultera en un comportement indéfini. Plus encore, POSIX demande que fd soit un descripteur de fichier valide.struct timeval { time_t tv_sec; /* secondes */ suseconds_t tv_usec; /* microsecondes */ };
Programmes multithreadés¶
Si un descripteur de fichier surveillé par select() est fermé dans un autre thread, le résultat est indéterminé. Sur certains systèmes UNIX, select() débloque et termine, avec une indication que le descripteur de fichier est prêt (une opération entrée/sortie ultérieur risque d'échouer avec une erreur, sauf si le descripteur de fichier a été réouvert entre le moment où select() termine et l'exécution des opérations entrée/sortie). Sur Linux (et d'autres systèmes), la fermeture du descripteur de fichier dans un autre thread n'a aucun effet sur select(). En résumé, toute application qui s'appuie sur un comportement particulier dans ce scénario doit être considérée comme boguée.Notes sur Linux¶
L'interface pselect() décrite dans cette page est implémentée par la glibc. L'appel système Linux sous-jacent est appelé pselect6(). Cet appel système a un comportement quelque peu différent de la fonction d'enrobage de la glibc.struct { const sigset_t *ss; /* pointeur vers l'ensemble de signaux */ size_t ss_len; /* taille (en octet) de l'objet pointé par 'ss' */ };
Cela permet à l'appel système d'obtenir à la fois le pointeur à l'ensemble de signaux et sa taille, tout en permettant à la plupart des architectures de ne prendre en charge qu'un maximum de 6 arguments pour un appel système.
BOGUES¶
Glibc 2.0 fournissait une version de pselect() qui n'avait pas d'argument sigmask.EXEMPLE¶
#include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> int main(void) { fd_set rfds; struct timeval tv; int retval; /* Surveiller stdin (fd 0) en attente d'entrées */ FD_ZERO(&rfds); FD_SET(0, &rfds); /* Attends jusqu'à 5 secondes. */ tv.tv_sec = 5; tv.tv_usec = 0; retval = select(1, &rfds, NULL, NULL, &tv); /* Considérer tv comme indéfini maintenant ! */ if (retval == -1) perror("select()"); else if (retval) printf("Des données sont disponibles maintenant\n"); /* FD_ISSET(0, &rfds) est alors vrai. */ else printf("Aucune donnée durant les cinq secondes.\n"); exit(EXIT_SUCCESS); }
VOIR AUSSI¶
accept(2), connect(2), poll(2), read(2), recv(2), send(2), sigprocmask(2), write(2), epoll(7), time(7)COLOPHON¶
Cette page fait partie de la publication 3.44 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies peuvent être trouvées à l'adresse <http://www.kernel.org/doc/man-pages/>.TRADUCTION¶
Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a <http://po4a.alioth.debian.org/> par l'équipe de traduction francophone au sein du projet perkamon <http://perkamon.alioth.debian.org/>. Christophe Blaess <http://www.blaess.fr/christophe/> (1996-2003), Alain Portal <http://manpagesfr.free.fr/> (2003-2006). Julien Cristau et l'équipe francophone de traduction de Debian (2006-2009). Veuillez signaler toute erreur de traduction en écrivant à <debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le paquet manpages-fr. Vous pouvez toujours avoir accès à la version anglaise de ce document en utilisant la commande « man -L C <section> <page_de_man> ».17 août 2012 | Linux |