select

SELECT(2)       Ð ÑководÑÑво пÑогÑаммиÑÑа Linux       SELECT(2)



ÐÐÐÐÐÐÐÐ
       select, pselect, 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);

       int pselect(int n, fd_set *readfds, fd_set *writefds, fd_set
       *exceptfds, const struct timespec *timeout, 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);

ÐÐÐСÐÐÐÐ
       ФÑнкÑии select и pselect ждÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑÑаÑÑÑа
       неÑколÑÐºÐ¸Ñ ÑайловÑÑ Ð´ÐµÑкÑипÑоÑов.

       Ðни поÑÑи иденÑиÑнÑ, ÑолÑко

       (i)    select иÑполÑзÑÐµÑ Ñайм-аÑÑ Ð² виде struct timeval
              (Ñ ÑекÑндами и микÑоÑекÑндами), Ñогда
              как pselect иÑполÑзÑÐµÑ struct timespec (Ñ
              ÑекÑндами и наноÑекÑндами).

       (ii)   ФÑнкÑÐ¸Ñ select Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð±Ð½Ð¾Ð²Ð¸ÑÑ Ð¿Ð°ÑамеÑÑ
              timeout, ÑÑÐ¾Ð±Ñ ÑообÑиÑÑ, ÑколÑко вÑемени
              оÑÑалоÑÑ.  ФÑнкÑÐ¸Ñ pselect не изменÑÐµÑ ÑÑоÑ
              паÑамеÑÑ.

       (iii)  ФÑнкÑÐ¸Ñ select не ÑодеÑÐ¶Ð¸Ñ Ð¿Ð°ÑамеÑÑа sigmask,
              и Ð²ÐµÐ´ÐµÑ ÑÐµÐ±Ñ ÐºÐ°Ðº pselect Ñ Ð¿Ð°ÑамеÑÑом sigmask,
              ÑавнÑм NULL.

       ÐÑÑлеживаÑÑÑÑ ÑÑи незавиÑимÑÑ Ð½Ð°Ð±Ð¾Ñа
       деÑкÑипÑоÑов.  Те, ÑÑо пеÑеÑиÑÐ»ÐµÐ½Ñ Ð² паÑамеÑÑе
       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, и воÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð¸ÑÑоднÑÑ
       маÑÐºÑ Ñигналов.

       ÐÐ´ÐµÑ pselect в Ñом, ÑÑо еÑли нÑжно подождаÑÑ
       ÑобÑÑиÑ: Ñигнала или акÑивноÑÑи на Ñайловом
       деÑкÑипÑоÑе, Ñо ÑÑебÑеÑÑÑ Ð°ÑомаÑÐ½Ð°Ñ Ð¿ÑовеÑка,
       ÑÑÐ¾Ð±Ñ Ð¿ÑедоÑвÑаÑиÑÑ race condition.  (ÐÑедположим,
       обÑабоÑÑик Ñигнала ÑÑÑанавливаеÑ
       глобалÑнÑй Ñлаг и возвÑаÑÐ°ÐµÑ ÑпÑавление.
       Тогда пÑовеÑка ÑÑого глобалÑного Ñлага,
       за коÑоÑой ÑледÑÐµÑ select(), Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑивеÑÑи к
       подвиÑаниÑ, еÑли Ñигнал поÑвлÑеÑÑÑ ÑÑазÑ
       поÑле пÑовеÑки, но пÑÑмо пеÑед вÑзовом select.
       С дÑÑгой ÑÑоÑонÑ, pselect позволÑÐµÑ ÑнаÑала
       заблокиÑоваÑÑ ÑигналÑ, обÑабоÑаÑÑ Ð¿ÑиÑедÑие
       ÑигналÑ, а заÑем вÑзваÑÑ pselect() Ñ Ð¶ÐµÐ»Ð°ÐµÐ¼Ð¾Ð¹
       sigmask, Ñем ÑамÑм Ð¸Ð·Ð±ÐµÐ³Ð°Ñ race condition.)  Так как
       Linux в наÑÑоÑÑее вÑÐµÐ¼Ñ Ð½Ðµ ÑодеÑÐ¶Ð¸Ñ ÑиÑÑемного
       вÑзова pselect(), ÑекÑÑÐ°Ñ ÑеализаÑÐ¸Ñ ÑÑой
       пÑоÑедÑÑÑ Ð² glibc вÑе еÑе ÑодеÑÐ¶Ð¸Ñ race condition.


ÐÐÐÐÐ ÐЩÐÐÐÐÐ ÐÐÐЧÐÐÐÐ
       ÐÑи ÑÑпеÑном завеÑÑении select и pselect
       возвÑаÑаÑÑ ÐºÐ¾Ð»Ð¸ÑеÑÑво деÑкÑипÑоÑов,
       наÑодÑÑиÑÑÑ Ð² набоÑÐ°Ñ Ð´ÐµÑкÑипÑоÑов, пÑиÑем ÑÑо
       колиÑеÑÑво Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑавнÑм нÑлÑ, еÑли
       Ñайм-аÑÑ Ð¸ÑÑекаеÑ, а инÑеÑеÑÑÑÑие Ð½Ð°Ñ ÑобÑÑиÑ
       Ñак и не пÑоизоÑли.  ÐÑи оÑибке возвÑаÑаеÑÑÑ
       -1, а errno ÑÑÑанавливаеÑÑÑ Ð´Ð¾Ð»Ð¶Ð½Ñм обÑазом;
       набоÑÑ Ð´ÐµÑкÑипÑоÑов и знаÑение timeout
       ÑÑановÑÑÑÑ Ð½ÐµÐ¾Ð¿ÑеделенÑ, поÑÑÐ¾Ð¼Ñ Ð¿Ñи оÑибке
       нелÑÐ·Ñ Ð¿Ð¾Ð»Ð°Ð³Ð°ÑÑÑÑ Ð½Ð° Ð¸Ñ Ð·Ð½Ð°Ñение.

ÐШÐÐÐÐ
       EBADF  Родном из набоÑов наÑодиÑÑÑ Ð½ÐµÐ²ÐµÑнÑй
              ÑайловÑй деÑкÑипÑоÑ.

       EINTR  ÐÑл пойман незаблокиÑованнÑй Ñигнал.

       EINVAL n оÑÑиÑаÑелÑно.

       ENOMEM ФÑнкÑÐ¸Ñ select не Ñмогла вÑделиÑÑ ÑÑаÑÑок
              памÑÑи Ð´Ð»Ñ Ð²Ð½ÑÑÑÐµÐ½Ð½Ð¸Ñ ÑаблиÑ.

ÐÐÐÐЧÐÐÐÐ
       РнекоÑоÑÑÑ Ð¿ÑогÑÐ°Ð¼Ð¼Ð°Ñ select вÑзÑваеÑÑÑ Ñ ÑÑемÑ
       пÑÑÑÑми набоÑами Ñайлов, n ÑавнÑм нÑлÑ, и
       ненÑлевÑм знаÑением timeout, ÑÑо ÑвлÑеÑÑÑ
       доволÑно пеÑеноÑимÑм ÑпоÑобом ÑделаÑÑ
       задеÑÐ¶ÐºÑ Ñ Ð¼Ð¸Ð»Ð»Ð¸ÑекÑндной ÑоÑноÑÑÑÑ.

       Ðод Linux 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");

           exit(0);
       }

СÐÐТÐÐТСТÐÐРСТÐÐÐÐРТÐÐ
       4.4BSD (ÑÑнкÑÐ¸Ñ select впеÑвÑе поÑвилаÑÑ Ð² 4.2BSD).
       ÐбÑÑно пеÑеноÑиÑÑÑ Ñ/на не-BSD ÑиÑÑемÑ,
       поддеÑживаÑÑие ÑÑÐ¾Ð²ÐµÐ½Ñ BSD-ÑокеÑов (вклÑÑаÑ
       ваÑианÑÑ System V).  Ðднако замеÑÑÑе, ÑÑо ваÑианÑÑ
       System V обÑÑно ÑÑÑанавливаÑÑ Ð·Ð½Ð°Ñение
       пеÑеменной timeout пеÑед вÑÑодом, а ваÑианÑ
       BSD -- неÑ.

       ФÑнкÑÐ¸Ñ pselect опÑеделена в IEEE Std 1003.1g-2000
       (POSIX.1g).  Ðе можно найÑи в glibc2.1 и позднее.
       Glibc2.0 ÑодеÑÐ¶Ð¸Ñ ÑÑнкÑÐ¸Ñ Ñ Ñаким именем, но без
       паÑамеÑÑа sigmask.

СÐÐТРРТÐÐÐÐ
       accept(2), connect(2), poll(2), read(2), recv(2), send(2),
       sigprocmask(2), write(2)

ÐÐÐ ÐÐÐÐ
       Copyright (C) Alexey Mahotkin <alexm@hsys.msk.ru> 2000-2001



Linux 1.2                     11 ÑевÑÐ°Ð»Ñ 1996                    SELECT(2)