НАЗВА
select, 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);
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 очікує зміни стану декількох файлових дескрипторів.
Відслідковуються три незалежних набори дескрипторів. Ті, що перераховані у readfds , будуть відслідковуватись для того, щоб виявити появу символів, доступних для зчитування (точніше кажучи, щоб взнати, чи не буде блоковано зчитування; дескриптор файлу також буде вказувати на кінець файлу); ті дескриптори, що вказані у writefds , будуть відслідковуватись для того, щоб взнати, чи не заблоковано процес запису; ті ж, що вказані в параметрі exceptfds , будуть відслідковуватись для виявлення виняткових ситуацій. На поверненні з функції, набори дескрипторів модифікуються, щоб показати, які дескриптори фактично змінили свій стан.
Для маніпулювання наборами існує чотири макроси: FD_ZERO - очищує набір; FD_SET і FD_CLR - додають вказаний дескриптор до набору чи видаляють його з набору; FD_ISSET - перевіряє, чи є дескриптор частиною набору; цей макрос стає в нагоді після повернення з функції select .
n на одиницю більше найбільшого номера дескриптора з всіх наборів.
R timeout - це верхня межа часу, який пройде перед поверненням з select . Можна використовувати нульове значення, в цьому випадку select завершиться негайно. Коли timeout дорівнює NULL (немає часу очікування), то select очікуватиме на зміни невизначений час.
ПОВЕРТАЄ ЗНАЧЕННЯ
В разі успішного виконання select повертає кількість дескрипторів, що знаходяться в наборах, ця кількість може дорівнювати нулю, якщо час очікування буде перевищено до того як відбудуться події що нас цікавлять. В разі помилки значення повернення рівне -1, а змінній errno присвоюється код помилки; набори дескрипторів і значення timeout стають невизначеними, тому в разі помилки не можна покладатися на їх значення.
КОДИ ПОМИЛОК
**EBADF** | В одному з наборів знаходиться невірний файловий дескриптор. |
**EINTR** | Було отримано незаблокований сиґнал. |
**EINVAL** | значення _n_ від'ємне. |
**ENOMEM** | Функція **select** не може виділити необхідний об'єм пам'яті для внутрішніх таблиць. |
ПРИМІТКИ
В деяких програмах select викликається трьома порожніми наборами файлів, при цьому n дорівнює нулю, а значення _R timeout _ не рівне нулю, і це непоганий спосіб зробити затримку з мілісекундною точністю, що діє на більшості платформ.
В Linux, timeout змінюється, щоб повідомити про невикористану кількість часу; більшість інших реалізацій не роблять цього. Це викликає проблеми, як в коді під Linux, що зчитує значення timeout і переноситься в інші операційні системи, так і в тому випадку, коли код переноситься в Linux, і використовує структуру 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;
/* Очікування вводу на stdin (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 - ні.
ДИВ. ТАКОЖ
accept(2), ?connect(2), ?poll(2), read(2), ?recv(2), ?send(2), write(2)