/* В соответствие с более ранними стандартами */
#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, const 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);
Эти функции идентичны, за исключением 3-х отличий между ними:
Отслеживаются 3 независимых набора описателей. Те, что перечислены в 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" и после этого восстанавливается оригинальная маска.
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
и
struct timespec {
long tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
(Однако, смотри ниже на версии POSIX 1003.1-2001.)
Иногда select вызывается с пустыми наборами (всеми тремя), n равным нулю и непустым timeout для переносимой реализации (portable) перехода в режим ожидания (sleep) на периоды с точностью более секунды.
В Linux функция select изменяет 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");
return 0;
}
struct timeval {
time_t tv_sec; /* секунды */
suseconds_t tv_usec; /* микросекунды */
};
В соответствие с прототипами, в классическом случае для использования
select
необходимо включать
<time.h>.
В случае POSIX 1003.1-2001 для использования
select
и
pselect
необходимо включать
<sys/select.h>.
Libc4 и libc5 не имеют файла заголовков
<sys/select.h>;
в glibc 2.0 и более поздних версиях он имеется.
В glibc 2.0 прототип
pselect
ошибочно определен всегда, в glibc 2.1-2.2.1 прототип
pselect
определен только когда определено
_GNU_SOURCE,
в glibc 2.2.2-2.2.4 прототип определен когда определено
_XOPEN_SOURCE
и его значение равно 600 или более.
Несомненно, начиная с POSIX 1003.1-2001, этот прототип включен по умолчанию.
Неявно связанные темы описаны в accept(2), connect(2), poll(2), read(2), recv(2), send(2), sigprocmask(2), write(2)
|
Закладки на сайте Проследить за страницей |
Created 1996-2025 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |