stringtranslate.com

seleccionar (Unix)

select es una llamada al sistema y una interfaz de programación de aplicaciones (API) ensistemas operativos similares a Unix y compatibles con POSIX para examinar el estado de los descriptores de archivos de los canales de entrada/salida abiertos. [1] La llamada al sistema de selección es similar a la función de encuesta introducida en UNIX System V y sistemas operativos posteriores. Sin embargo, con el problema c10k , tanto la selección como la encuesta han sido reemplazadas por kqueue , epoll , /dev/poll y puertos de finalización de E/S . [2]

Un uso común de select fuera de su uso declarado de esperar en identificadores de archivos es implementar una suspensión portátil de menos de un segundo . Esto se puede lograr pasando NULL para los tres argumentos fd_set y la duración del sueño deseado como argumento de tiempo de espera.

En el lenguaje de programación C , la llamada al sistema select se declara en el archivo de encabezado sys/select.h o unistd.h y tiene la siguiente sintaxis:

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

fd_set typeLos argumentos se pueden manipular con cuatro macros de utilidad: FD_SET(), FD_CLR(), FD_ZERO() y FD_ISSET() .

Select devuelve el número total de bits establecidos en readfds, writefds y errorfds , o cero si expiró el tiempo de espera y -1 en caso de error.

Los conjuntos de descriptores de archivos utilizados en la selección tienen un tamaño finito, según el sistema operativo. El sondeo de llamadas del sistema más nuevo proporciona una solución más flexible.

Ejemplo

#incluye <stdio.h> #incluye <stdlib.h> #incluye <cadena.h>   #incluye <sys/types.h> #incluye <sys/socket.h> #incluye <netinet/in.h> #incluye <netdb.h>    #incluye <sys/select.h> #incluye <fcntl.h> #incluye <unistd.h> #incluye <err.h> #incluye <errno.h>     #definir PUERTO "9421"/* prototipos de funciones */ void die ( const char * );  int main ( int argc , char ** argv ) { int sockfd , nuevo , maxfd , on = 1 , nready , i ;              struct addrinfo * res0 , * res , sugerencias ;     búfer de caracteres [ BUFSIZ ];  fd_set maestro , readfds ;   en terror ;  tamaño_t nbytes ;  ( void ) memset ( & sugerencias , '\0' , sizeof ( struct addrinfo ));    pistas . ai_familia = AF_INET ; pistas . ai_socktype = SOCK_STREAM ; pistas . ai_protocol = IPPROTO_TCP ; pistas . ai_flags = AI_PASSIVE ;            if ( 0 != ( error = getaddrinfo ( NULL , PORT , & sugerencias , & res0 ))) errx ( EXIT_FAILURE , "%s" , gai_strerror ( error ));            for ( res = res0 ; res ; res = res -> ai_next ) { if ( -1 == ( sockfd = socket ( res -> ai_family , res -> ai_socktype , res -> ai_protocol ))) { perror ( "socket( )" ); continuar ; }                     if ( -1 == ( setsockopt ( sockfd , SOL_SOCKET , SO_REUSEADDR , ( char * ) & on , sizeof ( int )))) { perror ( "setsockopt()" ); continuar ; }            if ( -1 == ( bind ( sockfd , res -> ai_addr , res -> ai_addrlen ))) { perror ( "bind()" ); continuar ; }          romper ; } si ( -1 == sockfd ) salir ( EXIT_FAILURE );     freeaddrinfo ( res0 ); if ( -1 == ( escuchar ( sockfd , 32 ))) morir ( "escuchar()" );      if ( -1 == ( fcntl ( sockfd , F_SETFD , O_NONBLOCK ))) muere ( "fcntl()" );       FD_ZERO ( & maestro ); FD_ZERO ( & readfds );  FD_SET ( sockfd y maestro ) ;  maxfd = calcetínfd ;   mientras ( 1 ) { memcpy ( & readfds , & maestro , tamaño de ( maestro ));      ( void ) printf ( "ejecutando select() \n " ); if ( -1 == ( nready = select ( maxfd + 1 , & readfds , NULL , NULL , NULL ))) die ( "select()" );           ( void ) printf ( "Número de descriptores listos: %d \n " , nready );  for ( i = 0 ; i <= maxfd && nready > 0 ; i ++ ) { if ( FD_ISSET ( i , & readfds )) { nready -- ;            if ( i == sockfd ) { ( void ) printf ( "Intentando aceptar() nuevas conexiones \n " );      if ( -1 == ( nuevo = aceptar ( sockfd , NULL , NULL ))) { if ( EWOULDBLOCK ! = errno ) morir ( "aceptar()" );              romper ; }  demás {  if ( -1 == ( fcntl ( nuevo , F_SETFD , O_NONBLOCK ))) muere ( "fcntl()" );       FD_SET ( nuevo y maestro ) ;  si ( maxfd < nuevo ) maxfd = nuevo ; } }         else { ( void ) printf ( "recv() datos de uno de los descriptores \n " );   nbytes = recv ( i , buffer , tamaño de ( buffer ), 0 ); if ( nbytes <= 0 ) { if ( EWOULDBLOCK != errno ) die ( "recv()" );                romper ; }  búfer [ nbytes ] = '\0' ; printf ( "%s" , buffer );     ( void ) printf ( "%zi bytes recibidos. \n " , nbytes );  cerrar ( yo ); FD_CLR ( i , & maestro );   } }  } } devolver 0 ; }  void die ( const char * msg ) { perror ( msg ); salir ( EXIT_FAILURE ); }     

Ver también

Referencias

  1. ^ Grupo de Investigación en Sistemas Informáticos (1994). "select, pselect - multiplexación de E/S síncrona". Referencia cruzada de BSD . NetBSD .
  2. ^ "Métodos de procesamiento de conexiones". nginx.org . _

enlaces externos