НАЗВА

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)