select()

Проверить наличие файлов, которые готовы к чтению или записи

Прототип:

#include <sys/select.h>
int select( int width,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout );
#define FD_SET( int fd, fd_set * fdset ) ...
#define FD_CLR( int fd, fd_set * fdset ) ...
#define FD_ISSET( int fd, fd_set * fdset ) ...
#define FD_ZERO( fd_set * fdset ) ...

Аргументы:

width
The number of descriptors to check in the given sets. Only the descriptors from 0 through (width - 1) in the descriptor sets are examined. Therefore, the value of width must be at least as large as:
(highest valued file descriptor in the sets) +1
readfds
NULL, or a pointer to a fd_set object that specifies the descriptors to check for files that are ready for reading. The function replaces the set with the file descriptors that are actually ready for reading.
writefds
NULL, or a pointer to a fd_set object that specifies the descriptors to check for files that are ready for writing. The function replaces the set with the file descriptors that are actually ready for writing.
exceptfds
NULL, or a pointer to a fd_set object that specifies the descriptors to check for files that have an exceptional condition pending. The function replaces the set with the file descriptors that actually have an exceptional condition pending.
timeout
NULL, or a pointer to a struct timeval that specifies how long to wait for the selection to complete.

Библиотека:

libc

Описание:

The select() function examines the file descriptor sets whose addresses are passed in readfds, writefds, and exceptfds to see if some of their descriptors are ready for reading, ready for writing, or have an exceptional condition pending. Any of readfds, writefds, and exceptfds may be NULL pointers if no descriptors are of interest.


Note: select() and the associated macros defined in <sys/select.h>, which <sys/time.h> includes.

The select() function replaces the given descriptor sets with subsets consisting of those descriptors that are ready for the requested operation, and returns the total number of ready descriptors in all the sets.

If timeout isn't NULL, it specifies a maximum interval to wait for the selection to complete. If timeout is NULL, select() blocks until one of the selected conditions occurs. To effect a poll, the timeout argument should be a non-NULL pointer, pointing to a zero-valued struct timeval.


Note: Because of the nature of time measurement, the function might actually wait longer than the specified time.

If the current operating system configuration supports a larger number of open files than is specified in FD_SETSIZE, you can increase the number of open file descriptors used with select() by changing the definition of FD_SETSIZE before including <sys/select.h> or <sys/time.h>.

If you use select() with a timeout, you should reset the timeout value after calling select().


Note: If you're using select() in conjunction with the socket API package, note that selecting for reading on a socket descriptor on which a listen() has been performed indicates that a subsequent accept() on that descriptor won't block.

Manipulating file-descriptor sets

At least the following macros are defined in <sys/select.h> for manipulating file-descriptor sets:

FD_ZERO( &fdset )
Initialize a descriptor set fdset to the null set.
FD_SET( fd, &fdset )
Add the file descriptor fd to the set fdset.
FD_CLR( fd, &fdset )
Remove fd from fdset.
FD_ISSET( fd, &fdset )
Is nonzero if fd is a member of fdset; otherwise, 0.

The behavior of these macros is undefined if a descriptor value is less than zero, or greater than or equal to FD_SETSIZE.

Возвращаемое значение:

Число готовых к операции дескрипторов для данного множества. Если возникла ошибка функция возвращает -1, код ошибки записывается в errno.

Коды ошибок:

EBADF
One of the descriptor sets specified an invalid descriptor.
EFAULT
One of the pointers given in the call referred to a nonexistent portion of the address space for the process.
EINTR
A signal was delivered before any of the selected events occurred, or before the time limit expired.
EINVAL
A component of the pointed-to time limit is outside the acceptable range: t_sec must be between 0 and 10^8, inclusive; t_usec must be greater than or equal to 0, and less than 10^6.

Примеры:

/*
* This example opens a console and a serial port for
* read mode, and calls select() with a 5 second timeout.
* It waits for data to be available on either descriptor.
*/
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/select.h>
int main( void )
{
int console, serial;
struct timeval tv;
fd_set rfd;
int n;
if ( ( console = open( "/dev/con1", O_RDONLY ) ) == -1 ||
( serial = open( "/dev/ser1", O_RDONLY ) ) == -1 )
{
perror( "open" );
return (EXIT_FAILURE);
}
/*
* Clear the set of read file descriptors, and
* add the two we just got from the open calls.
*/
FD_ZERO( &rfd );
FD_SET( console, &rfd );
FD_SET( serial, &rfd );
/*
* Set a 5 second timeout.
*/
tv.tv_sec = 5;
tv.tv_usec = 0;
switch ( n = select( 1 + max( console, serial ), &rfd, 0, 0, &tv ) )
{
case -1:
perror( "select" );
return (EXIT_FAILURE);
case 0:
puts( "select timed out" );
break;
default:
printf( "%d descriptors ready ...\n", n );
if ( FD_ISSET( console, &rfd ) )
puts( " -- console descriptor has data pending" );
if ( FD_ISSET( serial, &rfd ) )
puts( " -- serial descriptor has data pending" );
}
return (EXIT_SUCCESS);
}

Классификация:

POSIX 1003.1

Точка остановки потока
Нет
Обработчик прерываний
Нет
Обработчик сигналов
Нет
В потоке
Смотри ниже

Предостережения:

The select() function only works with raw file descriptors; it doesn't work with file descriptors in edited mode. See the ICANON flag in the description of the tcgetattr() function.

The select() function is thread safe as long as the fd sets used by each thread point to memory that is specific to that thread.

In Neutrino, if multiple threads block in select() on the same fd for the same condition, all threads may unblock when the condition is satisfied. This may differ from other implementations where only one thread may unblock.

Тематические ссылки:

struct timeval, errno, fcntl(), read(), sysconf(), tcsetattr(), write()




Предыдущий раздел: Описание API системной библиотеки