est un appel système et une interface de programmation (API) dessystèmes d'exploitation de type Unix et conformes à la norme POSIX permettant d'examiner l'état des descripteurs de fichiers des canaux d'entrée/sortie ouverts. Une version améliorée, prenant en charge le masquage des signaux, est `pselect` . L'appel système `select` est similaire à la fonction `poll`, plus récente , introduite dans UNIX System V et les systèmes d'exploitation ultérieurs. Cependant, suite au problème C10k , `select` et `poll` ont été remplacés par des fonctions telles que `kqueue` , `epoll` et les ports de complétion d'E/S .Une utilisation courante de `select`, en dehors de son utilisation principale pour l'attente sur les descripteurs de fichiers, consiste à implémenter une pause portable de moins d'une seconde . Ceci peut être réalisé en passant `NULL` pour les trois arguments de `fd_set`, et la durée de la pause souhaitée comme argument `timeout`.
En langage de programmation C , l'appel système select est déclaré dans le fichier d'en-tête sys/select.h ou unistd.h et possède la syntaxe suivante :
int select ( int nfds , fd_set * readfds , fd_set * writefds , fd_set * errorfds , struct timeval * timeout );
fd_set typeLes arguments peuvent être manipulés avec quatre macros utilitaires : FD_SET(), FD_CLR(), FD_ZERO() et FD_ISSET() .
La fonction Select renvoie le nombre total de bits définis dans readfds, writefds et errorfds , ou zéro si le délai d'attente a expiré, et -1 en cas d'erreur.
Les ensembles de descripteurs de fichiers utilisés par la commande `select` sont de taille finie et dépendent du système d'exploitation. L'appel système plus récent ` poll` offre une solution plus flexible.
Exemple #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <err.h> #include <fcntl.h> #include <netdb.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/select.h> #include <sys/types.h> #include <unistd.h> #définir PORT "9421" void die ( const char * msg ) { perror ( msg ); exit ( EXIT_FAILURE ); } typedef struct addrinfo AddressInfo ; int main ( int argc , char * argv []) { int sockfd ; AddressInfo * res0 ; tampon de caractères [ BUFSIZ ]; fd_set maître ; fd_set lire les descripteurs de fichiers ; erreur entière ; taille_t noctets ; memset ( & hints , '\0' , sizeof ( struct addrinfo )); AddressInfo * hints = { . ai_family = AF_INET , . ai_socktype = SOCK_STREAM , . ai_protocol = IPPROTO_TCP , . ai_flags = AI_PASSIVE }; if ( int error = getaddrinfo ( NULL , PORT , & hints , & res0 )) { errx ( EXIT_FAILURE , "%s" , gai_strerror ( error )); } for ( AddressInfo * res = res0 ; res ; res = res -> ai_next )) { if (( sockfd = socket ( res -> ai_family , res -> ai_socktype , res -> ai_protocol )) == -1 ) { perror ( "socket()" ); continuer ; } int on = 1 ; if ( setsockopt ( sockfd , SOL_SOCKET , SO_REUSEADDR , ( char * ) & on , sizeof ( int )) == -1 ) { perror ( "setsockopt()" ); continue ; } if ( bind ( sockfd , res- > ai_addr , res- > ai_addrlen ) == -1 ) { perror ( "bind()" ); continue ; } casser ; } si ( sockfd == -1 ) { retourner EXIT_FAILURE ; } freeaddrinfo ( res0 ); if ( listen ( sockfd , 32 ) == -1 ) { die ( "listen()" ); } if ( fcntl ( sockfd , F_SETFD , O_NONBLOCK ) == -1 ) { die ( "fcntl()" ); } FD_ZERO ( & master ); FD_ZERO ( & readfds ); FD_SET ( sockfd , & maître ); int maxfd = sockfd ; tant que ( vrai ) { memcpy ( & readfds , & master , sizeof ( master )); printf ( "exécution de select() " ); int nready ; if ( nready = select ( maxfd + 1 , & readfds , NULL , NULL , NULL ) == -1 ) { die ( "select()" ); } printf ( "Nombre de descripteurs prêts : %d " , nready ); pour ( int i = 0 ; i <= maxfd && nready > 0 ; i ++ ) { si ( FD_ISSET ( i , & readfds )) { nready -- ; if ( i == sockfd ) { printf ( "Tentative d'acceptation de nouvelles connexions " ); int newval ; if (( newval = accept ( sockfd , NULL , NULL )) == -1 ) { if ( EWOULDBLOCK != errno ) { die ( "accept()" ); } pause ; } sinon { if ( fcntl ( newval , F_SETFD , O_NONBLOCK ) == -1 ) { die ( "fcntl()" ); } FD_SET ( nouvelle valeur , & maître ); if ( maxfd < newval ) { maxfd = newval ; } } } else { printf ( "recv() données de l'un des descripteurs " ); nbytes = recv ( i , buffer , sizeof ( buffer ), 0 ); if ( nbytes <= 0 ) { if ( EWOULDBLOCK != errno ) { die ( "recv()" ); } casser ; } tampon [ nbytes ] = '\0' ; printf ( "%s" , tampon ); printf ( "%zi octets reçus. " , nbytes ); fermer ( i ); FD_CLR ( i , & maître ); } } } } renvoie 0 ; }
Plus d articles de Worldlex Wiki
Revenez a l index pour explorer davantage de pages sur l histoire, la science, la culture, la geographie et la societe en francais.
Explorer l index
sélectionner (Unix)
Source Worldlex Wiki
Langue Francais
Acces Gratuit