Rechercher une page de manuel
select
Langue: ru
Version: 11 февраля 1996 (fedora - 25/11/07)
Section: 2 (Appels système)
Sommaire
НАЗВАНИЕ
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-2001Contenus ©2006-2024 Benjamin Poulain
Design ©2006-2024 Maxime Vantorre