Функция select используется для проверки доступности данных в открытом дескрипторе.
Для использования функции в linux необходимо подключить заголовочные файлы:
#include <sys/time.h> #include <sys/types.h> #include <unistd.h>
или согласно POSIX.1-2001:
#include <sys/select.h>
В Windows функция определена в winsock.h и winsock2.h. Используется аналогично.
Но учтите, что в новой редакции функция имеет уже немного другой формат и называется pselect().
Прототип функции имеет вид:
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
Кроме того вам придётся использовать такие функции:
void FD_SET(int fd, fd_set *set); void FD_ZERO(fd_set *set);
С помощью этих функций задаётся поток.
Обратите внимание, что в функции select используется параметр int nfds — наивысший дескриптор. Его можно получить при помощи добавления 1 к полученному выше дескриптору.
Следующие три параметра функции select используються для задания отслеживаемых данных. Если дескриптор установлен в позиции fd_set *readfds дескриптор будет проверятся на возможность считывания данных; fd_set *writefds — доступность записи; fd_set *exceptfds — исключения.
Дискриптор будет проверятся в течении времени заданного в struct timeval, которая имеет вид:
struct timeval { long tv_sec; /* секунды */ long tv_usec; /* милисекунды */ };
Если данные не доступны будет возвращён «-1». Иначе будет возвращено количество дескрипторов «готовых» из трёх заданных.
Рассмотрим пример. Напишем программу, которая проверит доступность для чтения данных в потоке ввода.
Определим необходимые заголовочные файлы:
#include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h>
Определим необходимые переменные:
fd_set rfds; struct timeval tv; int retval;
Определим поток ввода данных (stdin — fd 0). При этом сначала необходимо обнулить rfds при помощи FD_ZERO():
FD_ZERO(&rfds); FD_SET(0, &rfds);
Укажем время ожидания данных:
tv.tv_sec = 5; tv.tv_usec = 0;
Вызовем функцию select:
retval = select(1, &rfds, NULL, NULL, &tv);
Осталось проверить результат операции:
if (retval == -1) perror("select()"); //выводим сообщение об ошибке else if (retval) printf("Данные доступны.\n"); else printf("Нет данных в течении 5 сек.\n");
Ну и конец каждой С программы:
exit(EXIT_SUCCESS);
После компиляции, в течении 5 секунд, введите данные и нажмите Enter, будет выведено сообщение о доступности данных, иначе через 5 секунд выведется сообщение о их недоступности. Учтите всё это произойдёт только если не будет возвращён -1 — ошибка выполнения функции.
ps эта функция очень полезна при работе с сокетами.