Article de reference

sélectionner (Unix)

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 ...

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