/* В соответствие с более ранними стандартами */
#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-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |