Provided by: manpages-ru_0.98-4_all bug

НАЗВАНИЕ

       select,   pselect,  FD_CLR,  FD_ISSET,  FD_SET,  FD_ZERO  -  синхронное
       мультиплексирование ввода-вывода

КРАТКАЯ СВОДКА

       #include <sys/time.h>
       #include <sys/types.h>
       #include <unistd.h>

       int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
       struct timeval *timeout);

       int   pselect(int   n,   fd_set   *readfds,  fd_set  *writefds,  fd_set
       *exceptfds, const struct timespec *timeout, sigset_t * sigmask);

       FD_CLR(int fd, fd_set *set);
       FD_ISSET(int fd, fd_set *set);
       FD_SET(int fd, fd_set *set);
       FD_ZERO(fd_set *set);

ОПИСАНИЕ

       Функции select и pselect ждут  изменения  статуса  нескольких  файловых
       дескрипторов.

       Они почти идентичны, только

       (i)    select  использует тайм-аут в виде struct timeval (с секундами и
              микросекундами), тогда как pselect использует struct timespec (с
              секундами и наносекундами).

       (ii)   Функция  select может обновить параметр timeout, чтобы сообщить,
              сколько времени осталось.   Функция  pselect  не  изменяет  этот
              параметр.

       (iii)  Функция  select  не содержит параметра sigmask, и ведет себя как
              pselect с параметром sigmask, равным NULL.

       Отслеживаются три независимых набора дескрипторов.  Те, что перечислены
       в  параметре  readfds,  будут  отслеживаться на предмет появления новых
       символов, доступных для чтения (говоря точнее, операция чтения не будет
       блокирована  --  в  частности,  файловый  дескриптор  находится в конце
       файла); те, что указаны в параметре writefds,  будут  отслеживаться  на
       предмет  того,  что  операция записи не будет заблокирована; те же, что
       указаны  в  параметре  exceptfds,  будут   отслеживаться   на   предмет
       исключительных  ситуаций.   При возврате из функции наборы дескрипторов
       модифицируются, чтобы показать, какие из них изменили свой статус.

       Для манипуляций наборами существуют  четыре  макроса:  FD_ZERO  очищает
       набор.   FD_SET  и  FD_CLR добавляют или удаляют заданный дескриптор из
       набора.  FD_ISSET проверяет, является ли дескриптор частью набора; этот
       макрос полезен после возврата из функции select.

       n на единицу больше самого большого номера дескриптора из всех наборов.

       timeout -- это верхняя граница времени, которое пройдет перед возвратом
       из  select.   Можно  использовать  ноль,  при  этом  select  завершится
       немедленно.  (Это полезно для  периодического  опроса.)   Если  timeout
       равен   NULL   (нет  тайм-аута),  то  select  будет  ожидать  изменений
       неопределенное время.

       sigmask -- это указатель на маску сигналов (см.  sigprocmask(2));  если
       этот  параметр не равен NULL, то pselect сначала замещает текущую маску
       сигналов на ту, на которую указывает sigmask, затем выполняет select, и
       восстанавливает исходную маску сигналов.

       Идея  pselect  в  том,  что  если  нужно подождать события: сигнала или
       активности на файловом дескрипторе, то  требуется  атомарная  проверка,
       чтобы  предотвратить  race condition.  (Предположим, обработчик сигнала
       устанавливает глобальный флаг и возвращает управление.  Тогда  проверка
       этого  глобального флага, за которой следует select(), может привести к
       подвисанию, если сигнал появляется сразу после проверки, но прямо перед
       вызовом   select.    С   другой   стороны,  pselect  позволяет  сначала
       заблокировать сигналы, обработать пришедшие сигналы,  а  затем  вызвать
       pselect()  с  желаемой sigmask, тем самым избегая race condition.)  Так
       как Linux в настоящее время не содержит  системного  вызова  pselect(),
       текущая  реализация  этой  процедуры  в  glibc  все  еще  содержит race
       condition.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

       При  успешном  завершении  select  и  pselect   возвращают   количество
       дескрипторов, находящихся в наборах дескрипторов, причем это количество
       может быть равным нулю, если  тайм-аут  истекает,  а  интересующие  нас
       события  так  и  не  произошли.   При  ошибке  возвращается -1, а errno
       устанавливается должным образом; наборы дескрипторов и значение timeout
       становятся  неопределены,  поэтому  при  ошибке нельзя полагаться на их
       значение.

ОШИБКИ

       EBADF  В одном из наборов находится неверный файловый дескриптор.

       EINTR  Был пойман незаблокированный сигнал.

       EINVAL n отрицательно.

       ENOMEM Функция select не смогла выделить участок памяти для  внутренних
              таблиц.

ЗАМЕЧАНИЕ

       В  некоторых  программах  select  вызывается  с  тремя пустыми наборами
       файлов, n равным нулю, и  ненулевым  значением  timeout,  что  является
       довольно   переносимым   способом  сделать  задержку  с  миллисекундной
       точностью.

       Под  Linux  timeout  изменяется,  чтобы  сообщить  количество  времени,
       которое  не  было использовано; большинство других реализаций не делают
       этого.  Это приводит к проблемам как в коде под Linux,  который  читает
       значение  timeout  и  переносится  в другие операционные системы, так и
       когда код переносится под Linux и использует при  этом  struct  timeval
       для  нескольких  функций  select  в  цикле без повторной инициализации.
       Считайте, что параметр timeout неопределен после  возврата  из  функции
       select.

ПРИМЕР

       #include <stdio.h>
       #include <sys/time.h>
       #include <sys/types.h>
       #include <unistd.h>

       int
       main(void)
       {
           fd_set rfds;
           struct timeval tv;
           int retval;

           /* Ждем, пока на стандартном вводе (fd 0) что-нибудь
              появится. */
           FD_ZERO(&rfds);
           FD_SET(0, &rfds);
           /* Ждем не больше пяти секунд. */
           tv.tv_sec = 5;
           tv.tv_usec = 0;

           retval = select(1, &rfds, NULL, NULL, &tv);
           /* Не полагаемся на значение tv! */

           if (retval)
               printf("Данные доступны.\n");
               /* Теперь FD_ISSET(0, &rfds) вернет истинное значение. */
           else
               printf("Данные не появились в течение пяти секунд.\n");

           exit(0);
       }

СООТВЕТСТВИЕ СТАНДАРТАМ

       4.4BSD (функция select впервые появилась в 4.2BSD).  Обычно переносится
       с/на  не-BSD  системы,  поддерживающие  уровень  BSD-сокетов   (включая
       варианты  System  V).   Однако  заметьте,  что варианты System V обычно
       устанавливают значение переменной  timeout  перед  выходом,  а  вариант
       BSD -- нет.

       Функция  pselect  определена  в  IEEE  Std 1003.1g-2000 (POSIX.1g).  Ее
       можно найти в glibc2.1 и позднее.  Glibc2.0 содержит  функцию  с  таким
       именем, но без параметра sigmask.

СМОТРИ ТАКЖЕ

       accept(2),    connect(2),    poll(2),    read(2),   recv(2),   send(2),
       sigprocmask(2), write(2)

ПЕРЕВОД

       Copyright (C) Alexey Mahotkin <alexm@hsys.msk.ru> 2000-2001