select

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



ÐÐЯ
       select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO -
       многопоÑоÑнÑй ÑинÑÑоннÑй ввод-вÑвод

ÐÐÐÐÐ
       /* Ð ÑооÑвеÑÑÑвии Ñ POSIX.1-2001, POSIX.1-2008 */
       #include <sys/select.h>

       /* Ð ÑооÑвеÑÑÑвие Ñ Ð±Ð¾Ð»ÐµÐµ Ñанними ÑÑандаÑÑами */
       #include <sys/time.h>
       #include <sys/types.h>
       #include <unistd.h>

       int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);

       void FD_CLR(int fd, fd_set *set);
       int  FD_ISSET(int fd, fd_set *set);
       void FD_SET(int fd, fd_set *set);
       void FD_ZERO(fd_set *set);

       #include <sys/select.h>

       int pselect(int nfds, fd_set *readfds, fd_set *writefds,
                   fd_set *exceptfds, const struct timespec *timeout,
                   const sigset_t *sigmask);

   ТÑÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¼Ð°ÐºÑоÑа ÑеÑÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑвойÑÑв Ð´Ð»Ñ glibc
   (Ñм. feature_test_macros(7)):

       pselect(): _POSIX_C_SOURCE >= 200112L

ÐÐÐСÐÐÐÐ
       ÐÑÐ·Ð¾Ð²Ñ select() и pselect() позволÑÑÑ Ð¿ÑогÑаммам
       оÑÑлеживаÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑайловÑÑ
       деÑкÑипÑоÑов ожидаÑ, когда один или более
       ÑайловÑÑ Ð´ÐµÑкÑипÑоÑов ÑÑанÑÑ Â«Ð³Ð¾ÑовÑ» длÑ
       опеÑаÑии ввода-вÑвода опÑеделÑнного Ñипа
       (напÑимеÑ, ввода). ФайловÑй деÑкÑипÑоÑ
       ÑÑиÑаеÑÑÑ Ð³Ð¾ÑовÑм, еÑли к Ð½ÐµÐ¼Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾
       пÑимениÑÑ ÑооÑвеÑÑÑвÑÑÑÑÑ Ð¾Ð¿ÐµÑаÑиÑ
       ввода-вÑвода (напÑимеÑ, read(2)) без
       блокиÑовки или оÑÐµÐ½Ñ Ð¼Ð°Ð»ÐµÐ½Ñкий write(2)).

       ÐÑзов select() Ð¼Ð¾Ð¶ÐµÑ ÑледиÑÑ ÑолÑко за номеÑами
       ÑайловÑÑ Ð´ÐµÑкÑипÑоÑов, коÑоÑÑе менÑÑе FD_SETSIZE;
       вÑзов poll(2) не Ð¸Ð¼ÐµÐµÑ ÑÑого огÑаниÑениÑ.
       СмоÑÑиÑе ÐÐФÐÐТЫ.

       РабоÑа select() и pselect() иденÑиÑна за
       иÑклÑÑением ÑÑÑÑ Ð¼Ð¾Ð¼ÐµÐ½Ñов:

       (i)    РвÑзове select() вÑÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð·Ð°Ð´Ð°ÑÑÑÑ Ð²
              ÑÑÑÑкÑÑÑе struct timeval (Ñ ÑекÑндами и
              микÑоÑекÑндами), а в pselect() иÑполÑзÑеÑÑÑ
              ÑÑÑÑкÑÑÑа struct timespec (Ñ ÑекÑндами и
              наноÑекÑндами).

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

       (iii)  ÐÑзов select() не Ð¸Ð¼ÐµÐµÑ Ð°ÑгÑменÑа sigmask, и
              ведÑÑ ÑÐµÐ±Ñ Ñакже как pselect(), еÑли пÑи
              вÑзове бÑло Ñказано знаÑение sigmask
              Ñавное NULL.

       ÐÑÑлеживаÑÑÑÑ 3 незавиÑимÑÑ Ð½Ð°Ð±Ð¾Ñа ÑайловÑÑ
       деÑкÑипÑоÑов. Ð ÑеÑ, ÑÑо пеÑеÑиÑÐ»ÐµÐ½Ñ Ð² readfds,
       бÑÐ´ÐµÑ Ð¾ÑÑлеживаÑÑÑÑ Ð¿Ð¾Ñвление Ñимволов,
       доÑÑÑпнÑÑ Ð´Ð»Ñ ÑÑÐµÐ½Ð¸Ñ (говоÑÑ Ð±Ð¾Ð»ÐµÐµ ÑоÑно,
       пÑовеÑÑеÑÑÑ Ð´Ð¾ÑÑÑпноÑÑÑ ÑÑÐµÐ½Ð¸Ñ Ð±ÐµÐ· блокиÑовки;
       в ÑаÑÑноÑÑи, ÑайловÑй деÑкÑипÑÐ¾Ñ Ð³Ð¾Ñов длÑ
       ÑÑениÑ, еÑли он ÑказÑÐ²Ð°ÐµÑ Ð½Ð° ÐºÐ¾Ð½ÐµÑ Ñайла);
       деÑкÑипÑоÑÑ, ÑказаннÑе в writefds, бÑдÑÑ
       оÑÑлеживаÑÑÑÑ Ð´Ð»Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑи запиÑи без
       блокиÑовки, еÑли доÑÑÑпно пÑоÑÑÑанÑÑво длÑ
       запиÑи (ÑоÑÑ Ð¿Ñи болÑÑом колиÑеÑÑве даннÑÑ
       Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи бÑÐ´ÐµÑ Ð¿Ð¾-пÑÐµÐ¶Ð½ÐµÐ¼Ñ Ð²Ñполнена
       блокиÑовка), а ÑказаннÑе в exceptfds, бÑдÑÑ
       оÑÑлеживаÑÑÑÑ Ð´Ð»Ñ Ð¾Ð±Ð½Ð°ÑÑÐ¶ÐµÐ½Ð¸Ñ Ð¸ÑклÑÑиÑелÑнÑÑ
       ÑиÑÑаÑий. ÐÑи возвÑаÑе из вÑзова набоÑÑ
       изменÑÑÑÑÑ, показÑÐ²Ð°Ñ ÐºÐ°ÐºÐ¸Ðµ ÑайловÑе
       деÑкÑипÑоÑÑ ÑакÑиÑеÑки изменили ÑоÑÑоÑние.
       ÐнаÑение лÑбого из ÑÑÑÑ Ð½Ð°Ð±Ð¾Ñов ÑайловÑÑ
       деÑкÑипÑоÑов Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ñавно NULL, еÑли
       Ñлежение за опÑеделÑннÑм клаÑÑом ÑобÑÑий
       над ÑайловÑми деÑкÑипÑоÑами не ÑÑебÑеÑÑÑ.

       ÐÐ»Ñ Ð¼Ð°Ð½Ð¸Ð¿ÑлÑÑий набоÑами ÑÑÑеÑÑвÑÑÑ ÑеÑÑÑе
       макÑоÑа: FD_ZERO() оÑиÑÐ°ÐµÑ Ð½Ð°Ð±Ð¾Ñ;  FD_SET()
       добавлÑÐµÑ Ð·Ð°Ð´Ð°Ð½Ð½Ñй ÑайловÑй деÑкÑипÑÐ¾Ñ Ðº
       набоÑÑ; FD_CLR() ÑдалÑÐµÑ ÑайловÑй деÑкÑипÑÐ¾Ñ Ð¸Ð·
       набоÑа; FD_ISSET() пÑовеÑÑеÑ, ÑвлÑеÑÑÑ Ð»Ð¸ ÑайловÑй
       деÑкÑипÑÐ¾Ñ ÑаÑÑÑÑ Ð½Ð°Ð±Ð¾Ñа. ÐÑи макÑоÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ
       поÑле возвÑаÑа из вÑзова select().

       ÐнаÑение nfds на единиÑÑ Ð±Ð¾Ð»ÑÑе Ñамого
       болÑÑого номеÑа Ñайлового деÑкÑипÑоÑа из
       вÑÐµÑ ÑÑÑÑ Ð½Ð°Ð±Ð¾Ñов.

       РаÑгÑменÑе timeout ÑказÑваеÑÑÑ Ð¸Ð½ÑеÑвал, на
       коÑоÑÑй должен заблокиÑоваÑÑÑÑ select() в
       ожидании гоÑовноÑÑи Ñайлового
       деÑкÑипÑоÑа. ÐÑзов бÑÐ´ÐµÑ Ð±Ð»Ð¾ÐºÐ¸Ñован пока:

       *  ÑайловÑй деÑкÑипÑÐ¾Ñ Ð½Ðµ ÑÑÐ°Ð½ÐµÑ Ð³Ð¾Ñов;

       *  вÑзов не пÑеÑвÑÑÑÑ Ð¾Ð±ÑабоÑÑиком Ñигнала;

       *  не иÑÑеÑÑÑ Ð²ÑÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ.

       ÐамеÑим, ÑÑо инÑеÑвал timeout бÑÐ´ÐµÑ Ð¾ÐºÑÑглÑн Ñ
       ÑоÑноÑÑÑÑ ÑиÑÑемнÑÑ ÑаÑов, а из-за задеÑжки пÑи
       планиÑовании в ÑдÑе блокиÑÑÑÑий инÑеÑвал
       бÑÐ´ÐµÑ Ð½ÐµÐ¼Ð½Ð¾Ð³Ð¾ болÑÑе. ÐÑли оба Ð¿Ð¾Ð»Ñ ÑÑÑÑкÑÑÑÑ
       timeval ÑÐ°Ð²Ð½Ñ Ð½ÑлÑ, Ñо select() завеÑÑиÑÑÑ
       немедленно (полезно пÑи опÑоÑе (polling)).
       ÐÑли знаÑение timeout Ñавно NULL (вÑÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ
       не задано), Ñо select() Ð¼Ð¾Ð¶ÐµÑ Ð±Ð»Ð¾ÐºÐ¸ÑоваÑÑ
       ÑабоÑÑ Ð½ÐµÐ¾Ð¿ÑеделÑнно долго.

       ÐнаÑение sigmask ÑвлÑеÑÑÑ ÑказаÑелем на маÑкÑ
       Ñигналов (ÑмоÑÑиÑе sigprocmask(2)); еÑли оно не
       Ñавно NULL, Ñо ÑнаÑала pselect() заменÑÐµÑ ÑекÑÑÑÑ
       маÑÐºÑ Ñигналов на заданнÑÑ sigmask, заÑем
       вÑполнÑÐµÑ ÑÑнкÑÐ¸Ñ Â«select», поÑле Ñего
       воÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð¿ÐµÑвонаÑалÑнÑÑ ÑигналÑнÑÑ
       маÑкÑ.

       ÐÑоме ÑазлиÑÐ¸Ñ Ð² ÑоÑноÑÑи аÑгÑменÑа timeout
       вÑзов pselect()

           ready = pselect(nfds, &readfds, &writefds, &exceptfds,
                           timeout, &sigmask);

       ÑквиваленÑен аÑомаÑÐ½Ð¾Ð¼Ñ Ð²ÑполнениÑ
       ÑледÑÑÑÐ¸Ñ Ð²Ñзовов:

           sigset_t origmask;

           pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
           ready = select(nfds, &readfds, &writefds, &exceptfds, timeout);
           pthread_sigmask(SIG_SETMASK, &origmask, NULL);

       ÐÑиÑина необÑодимоÑÑи pselect() в Ñом, ÑÑо еÑли
       нÑжно ждаÑÑ ÐºÐ°ÐºÐ¾Ð³Ð¾-Ñо Ñигнала или
       гоÑовноÑÑи Ñайлового деÑкÑипÑоÑа, Ñо
       необÑодимо аÑомаÑное ÑеÑÑиÑование длÑ
       Ð¸Ð·Ð±ÐµÐ¶Ð°Ð½Ð¸Ñ ÑоÑÑÑзаÑелÑноÑÑи. (ÐÑедположим, ÑÑо
       обÑабоÑÑик Ñигнала ÑÑÑанавливаеÑ
       глобалÑнÑй Ñлаг и завеÑÑаеÑÑÑ. Ð ÑÑом ÑлÑÑае
       ÑеÑÑ ÑÑого глобалÑного Ñлага поÑле вÑзова
       select() мог Ð±Ñ Ð´Ð»Ð¸ÑÑÑÑ Ð±ÐµÑконеÑно, еÑли Ñигнал
       пÑибÑл Ð±Ñ ÑÑÐ°Ð·Ñ Ð¿Ð¾Ñле ÑеÑÑиÑованиÑ, но до
       вÑзова. РоÑлиÑие Ð¾Ñ ÑÑого, pselect() позволÑеÑ
       ÑнаÑала заблокиÑоваÑÑ ÑигналÑ, обÑабоÑаÑÑ
       Ñже поÑÑÑпивÑие и заÑем вÑзваÑÑ pselect() Ñ
       желаемÑм знаÑением sigmask, избегаÑ
       ÑоÑÑÑзаÑелÑноÑÑи.)

   ÐÑÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ
       ÐÑполÑзÑемÑе ÑÑÑÑкÑÑÑÑ Ð²Ñемени опÑÐµÐ´ÐµÐ»ÐµÐ½Ñ Ð²
       <sys/time.h> и вÑглÑдÑÑ ÑледÑÑÑим обÑазом:

           struct timeval {
               long    tv_sec;         /* ÑекÑÐ½Ð´Ñ */
               long    tv_usec;        /* микÑоÑекÑÐ½Ð´Ñ */
           };

       и

           struct timespec {
               long    tv_sec;         /* ÑекÑÐ½Ð´Ñ */
               long    tv_nsec;        /* наноÑекÑÐ½Ð´Ñ */
           };

       (Ðднако, ÑмоÑÑиÑе ниже пÑо веÑÑÐ¸Ñ POSIX.1.)

       Ðногда select() вÑзÑваеÑÑÑ Ñ Ð¿ÑÑÑÑми набоÑами
       (вÑеми ÑÑемÑ), nfds ÑавнÑм нÑÐ»Ñ Ð¸ непÑÑÑÑм timeout
       Ð´Ð»Ñ Ð¿ÐµÑеноÑимой ÑеализаÑии пеÑеÑода в
       Ñежим Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ (sleep) на пеÑÐ¸Ð¾Ð´Ñ Ñ ÑоÑноÑÑÑÑ
       менее ÑекÑндÑ.

       Ð Linux вÑзов select() изменÑÐµÑ timeout Ð´Ð»Ñ Ð¾ÑÑажениÑ
       вÑемени, пÑоведÑнного не в Ñежиме
       ожиданиÑ; болÑÑÐ°Ñ ÑаÑÑÑ Ð´ÑÑÐ³Ð¸Ñ ÑеализаÑий
       ÑÑого не Ð´ÐµÐ»Ð°ÐµÑ (ÑоглаÑно POSIX.1 допÑÑкаеÑÑÑ
       лÑбой из ÑÑÐ¸Ñ Ð²Ð°ÑианÑов). ÐÑо вÑзÑваеÑ
       пÑÐ¾Ð±Ð»ÐµÐ¼Ñ ÐºÐ°Ðº пÑи пеÑеноÑе кода Linux,
       ÑиÑаÑÑего timeout, на дÑÑгие опеÑаÑионнÑе
       ÑиÑÑемÑ, Ñак и пÑи пеÑеноÑе на Linux кода,
       иÑполÑзÑÑÑего struct timeval Ð´Ð»Ñ Ð¼Ð½Ð¾Ð³Ð¾ÐºÑаÑного
       вÑзова select() в Ñикле без его
       пеÑеиниÑиализаÑии. Ðо избежание ÑÑого
       ÑледÑÐµÑ ÑÑиÑаÑÑ, ÑÑо знаÑение timeout не
       опÑеделено поÑле возвÑаÑа из select().

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

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

       EINTR  ÐÑи вÑполнении поÑÑÑпил Ñигнал; Ñм.
              signal(7).

       EINVAL ÐнаÑение nfds оÑÑиÑаÑелÑно или пÑевÑÑаеÑ
              огÑаниÑение ÑеÑÑÑÑа RLIMIT_NOFILE (ÑмоÑÑиÑе
              getrlimit(2)).

       EINVAL ÐнаÑение, ÑодеÑжаÑееÑÑ Ð²Ð½ÑÑÑи timeout,
              некоÑÑекÑно.

       ENOMEM Ðе ÑдалоÑÑ Ð²ÑделиÑÑ Ð¿Ð°Ð¼ÑÑÑ Ð´Ð»Ñ Ð²Ð½ÑÑÑенниÑ
              ÑаблиÑ.

ÐÐРСÐÐ
       ÐÑзов pselect() бÑл добавлен в ÑдÑо Linux веÑÑии
       2.6.16. Ðо ÑÑого pselect() ÑмÑлиÑовалÑÑ Ð² glibc (но, Ñм.
       ÐÐФÐÐТЫ).

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

       ÐÑзов pselect() опÑеделÑн в ÑÑандаÑÑÐ°Ñ POSIX.1g, в
       POSIX 1004.1-2001 и POSIX.1-2008.

ÐÐÐÐЧÐÐÐЯ
       fd_set пÑедÑÑавлÑÐµÑ Ñобой бÑÑÐµÑ ÑикÑиÑованного
       ÑазмеÑа. ÐÑполнение FD_CLR() или FD_SET() Ñ
       оÑÑиÑаÑелÑнÑм знаÑением fd, ÑавнÑм или
       болÑÑим Ñем FD_SETSIZE, пÑÐ¸Ð²Ð¾Ð´Ð¸Ñ Ðº
       неопÑеделÑÐ½Ð½Ð¾Ð¼Ñ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ñ. Ðолее Ñого,
       ÑоглаÑно POSIX fd должен бÑÑÑ ÐºÐ¾ÑÑекÑнÑм
       ÑайловÑм деÑкÑипÑоÑом.

       РнекоÑоÑÑÑ ÑиÑÑÐµÐ¼Ð°Ñ UNIX вÑзов select() можеÑ
       завеÑÑаÑÑÑÑ Ñ Ð¾Ñибкой EAGAIN, еÑли ÑиÑÑеме не
       ÑдаÑÑÑÑ Ð²ÑделиÑÑ Ð²Ð½ÑÑÑенние ÑеÑÑÑÑÑ ÑдÑа, вмеÑÑо
       оÑибки ENOMEM, как ÑÑо пÑоиÑÑÐ¾Ð´Ð¸Ñ Ð² Linux. Ð POSIX ÑÑа
       оÑибка Ñказана Ð´Ð»Ñ poll(2), но не Ð´Ð»Ñ select(). Ð
       пеÑеноÑимÑÑ Ð¿ÑогÑÐ°Ð¼Ð¼Ð°Ñ Ð»ÑÑÑе ожидаÑÑ EAGAIN в
       Ñикле, как Ð´Ð»Ñ EINTR.

       ЧÑо каÑаеÑÑÑ Ð·Ð°Ð´ÐµÐ¹ÑÑвованнÑÑ Ñипов,
       клаÑÑиÑеÑким ваÑианÑом ÑвлÑеÑÑÑ ÑÑÑÑкÑÑÑа timeval Ñ
       двÑÐ¼Ñ Ð¿Ð¾Ð»Ñми Ñипа long (как показано ниже),
       коÑоÑÐ°Ñ Ð¾Ð¿Ñеделена в <sys/time.h>. Ð POSIX.1:

           struct timeval {
               time_t         tv_sec;     /* ÑекÑÐ½Ð´Ñ */
               suseconds_t    tv_usec;    /* микÑоÑекÑÐ½Ð´Ñ */
           };

       где ÑÑÑÑкÑÑÑа опÑеделена в <sys/select.h>, а ÑипÑ
       даннÑÑ time_t и suseconds_t опÑÐµÐ´ÐµÐ»ÐµÐ½Ñ Ð² <sys/types.h>.

       ЧÑо каÑаеÑÑÑ Ð¿ÑоÑоÑипов, клаÑÑиÑеÑким
       ваÑианÑом ÑвлÑеÑÑÑ Ð¾Ð±ÑÑвление select() в <time.h>.
       СоглаÑно POSIX.1 обÑÑÐ²Ð»ÐµÐ½Ð¸Ñ select() и pselect()
       Ð´Ð¾Ð»Ð¶Ð½Ñ Ð²ÐºÐ»ÑÑаÑÑÑÑ Ð² <sys/select.h>.

       Ð <sys/select.h> из glibc 2.0 Ñказан оÑибоÑнÑй
       пÑоÑоÑип pselect(). Ð glibc 2.1 до веÑÑии 2.2.1 pselect()
       доÑÑÑпен пÑи опÑеделÑнном _GNU_SOURCE.
       ТÑебованиÑ, коÑоÑÑе необÑÐ¾Ð´Ð¸Ð¼Ñ Ð´Ð»Ñ ÑабоÑÑ Ñ
       glibc наÑÐ¸Ð½Ð°Ñ Ñ Ð²ÐµÑÑии 2.2.2, Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ñ Ð² Ñазделе
       ÐÐÐÐÐ .

   ÐногониÑиевÑе пÑиложениÑ
       ÐÑли Ñайловой деÑкÑипÑоÑ, оÑÑлеживаемÑй
       select(), закÑÑваеÑÑÑ Ð² дÑÑгой ниÑи, Ñо ÑезÑлÑÑаÑ
       непÑедÑказÑем. РнекоÑоÑÑÑ ÑиÑÑÐµÐ¼Ð°Ñ UNIX select()
       ÑазблокиÑÑеÑÑÑ Ð¸ возвÑаÑÐ°ÐµÑ Ð²Ñполнение Ñ
       Ñказанием Ñого, ÑÑо ÑайловÑй деÑкÑипÑоÑ
       гоÑов (поÑледÑÑÑÐ°Ñ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ð²Ð²Ð¾Ð´Ð°-вÑвода,
       веÑоÑÑно, завеÑÑиÑÑÑ Ñ Ð¾Ñибкой, еÑли дÑÑгой
       ÑайловÑй деÑкÑипÑÐ¾Ñ Ð½Ðµ пеÑеоÑкÑоеÑÑÑ Ð¼ÐµÐ¶Ð´Ñ
       возвÑаÑом select() и вÑполнением опеÑаÑий
       ввода-вÑвода). Ð Linux (и некоÑоÑÑÑ Ð´ÑÑгиÑ
       ÑиÑÑемаÑ), закÑÑÑие Ñайлового деÑкÑипÑоÑа в
       дÑÑгой ниÑи не влиÑÐµÑ Ð½Ð° select(). РезÑмиÑÑÑ,
       лÑбое пÑиложение, коÑоÑое полагаеÑÑÑ Ð½Ð°
       опÑеделÑнное поведение в Ñаком ÑÑенаÑии,
       должно ÑÑиÑаÑÑÑÑ Ð¾ÑибоÑнÑм.

   ÐÑлиÑÐ¸Ñ Ð¼ÐµÐ¶Ð´Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñекой C и ÑдÑом
       ЯдÑо Linux ÑазÑеÑÐ°ÐµÑ Ð½Ð°Ð±Ð¾ÑÑ ÑайловÑÑ
       деÑкÑипÑоÑов лÑбого ÑазмеÑа, опÑеделÑÑ
       Ð´Ð»Ð¸Ð½Ñ Ð½Ð°Ð±Ð¾Ñа по знаÑÐµÐ½Ð¸Ñ nfds. Ðднако в
       ÑеализаÑии glibc Ñип fd_set Ð¸Ð¼ÐµÐµÑ ÑикÑиÑованнÑй
       ÑазмеÑ. СмоÑÑиÑе Ñакже ÐÐФÐÐТЫ.

       ÐнÑеÑÑÐµÐ¹Ñ pselect(), опиÑаннÑй в ÑÑой ÑÑÑаниÑе,
       Ñеализован в glibc. ÐÐ»Ñ ÑÑого иÑполÑзÑеÑÑÑ
       ÑиÑÑемнÑй вÑзов pselect6(). Ðоведение данного
       ÑиÑÑемного вÑзова неÑколÑко оÑлиÑаеÑÑÑ Ð¾Ñ
       обÑÑÑоÑной ÑÑнкÑии glibc.

       Ð Linux ÑиÑÑемнÑй вÑзов pselect6() изменÑеÑ
       ÑодеÑжимое Ñвоего аÑгÑменÑа timeout. Ðднако,
       обÑÑÑоÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ glibc ÑкÑÑÐ²Ð°ÐµÑ ÑÑо поведение
       иÑполÑзÑÑ Ð»Ð¾ÐºÐ°Ð»ÑнÑÑ Ð¿ÐµÑеменнÑÑ Ð´Ð»Ñ Ð°ÑгÑменÑа
       timeout пÑи пеÑедаÑе в ÑиÑÑемнÑй вÑзов. Таким
       обÑазом, ÑÑнкÑÐ¸Ñ pselect() в glibc не изменÑеÑ
       Ñвой аÑгÑÐ¼ÐµÐ½Ñ timeout; ÑÑо поведение ÑÑебÑеÑÑÑ Ð²
       POSIX.1-2001.

       ÐоÑледний аÑгÑÐ¼ÐµÐ½Ñ ÑиÑÑемного вÑзова pselect6()
       не ÑвлÑеÑÑÑ ÑказаÑелем sigset_t *, он
       пÑедÑÑавлÑÐµÑ Ñобой ÑÑÑÑкÑÑÑÑ Ð² виде:

           struct {
               const sigset_t *ss;     /* ÑказаÑÐµÐ»Ñ Ð½Ð° Ð½Ð°Ð±Ð¾Ñ Ñигналов */
               size_t          ss_len; /* ÑÐ°Ð·Ð¼ÐµÑ (в байÑаÑ) обÑекÑа, на коÑоÑÑй
                                          ÑказÑÐ²Ð°ÐµÑ Â«ss» */
           };

       ÐÑо позволÑÐµÑ ÑиÑÑÐµÐ¼Ð½Ð¾Ð¼Ñ Ð²ÑÐ·Ð¾Ð²Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð¸
       ÑказаÑÐµÐ»Ñ Ð½Ð° Ð½Ð°Ð±Ð¾Ñ Ñигналов, Ñак как в
       болÑÑинÑÑве аÑÑиÑекÑÑÑ ÑиÑÑемнÑм вÑзовам
       можно пеÑедаÑÑ Ð¼Ð°ÐºÑимÑм 6 аÑгÑменÑов.

ÐÐФÐÐТЫ
       Ð POSIX ÑазÑеÑено в ÑеализаÑии опÑеделÑÑÑ
       веÑÑнее огÑаниÑение, обÑÑвлÑемое ÑеÑез
       конÑÑанÑÑ FD_SETSIZE, Ð´Ð»Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð° ÑайловÑÑ
       деÑкÑипÑоÑов, коÑоÑÑй можно задаÑÑ Ð² набоÑе
       ÑайловÑÑ Ð´ÐµÑкÑипÑоÑов. ЯдÑо Linux не имееÑ
       ÑикÑиÑованного огÑаниÑениÑ, но ÑеализаÑиÑ
       glibc иÑполÑзÑÐµÑ Ñип fd_set поÑÑоÑнного ÑазмеÑа,
       опÑеделÑÐµÑ FD_SETSIZE ÑавнÑм 1024, а Ñакже
       пÑедоÑÑавлÑÐµÑ Ð½Ð°Ð±Ð¾Ñ Ð¼Ð°ÐºÑоÑов опеÑаÑий FD_*(),
       ÑÑиÑÑваÑÑÐ¸Ñ ÑÑо огÑаниÑение. ÐÐ»Ñ ÑÐ»ÐµÐ¶ÐµÐ½Ð¸Ñ Ð·Ð°
       ÑайловÑми деÑкÑипÑоÑами болÑÑими Ñем 1023
       иÑполÑзÑйÑе вÑзов poll(2).

       Glibc 2.0 пÑедоÑÑавлÑÐµÑ Ð²ÐµÑÑÐ¸Ñ pselect(), коÑоÑÐ°Ñ Ð½Ðµ
       пÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ Ð°ÑгÑÐ¼ÐµÐ½Ñ sigmask.

       ÐаÑÐ¸Ð½Ð°Ñ Ñ Ð²ÐµÑÑии 2.1, glibc пÑедоÑÑавлÑÐµÑ ÑмÑлÑÑиÑ
       pselect(), коÑоÑÐ°Ñ Ñеализована Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ
       sigprocmask(2) и select(). ÐÑа ÑеализаÑÐ¸Ñ Ð¾ÑÑаÑÑÑÑ
       ÑÑзвимой к Ñой Ñамой ÑоÑÑÑзаÑелÑноÑÑи, длÑ
       ÑÑÑÑÐ°Ð½ÐµÐ½Ð¸Ñ ÐºÐ¾ÑоÑой и бÑл ÑазÑабоÑан pselect(). Ð
       ÑовÑеменнÑÑ Ð²ÐµÑÑии glibc иÑполÑзÑеÑÑÑ
       (беÑÑоÑÑÑзаÑелÑнÑй) ÑиÑÑемнÑй вÑзов pselect(),
       еÑли он пÑедоÑÑавлÑеÑÑÑ ÑдÑом.

       Ð ÑиÑÑÐµÐ¼Ð°Ñ Ð±ÐµÐ· pselect(), надÑжного (и более
       пеÑеноÑимого) пеÑеÑваÑа Ñигнала можно
       доÑÑиÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑÑÑка Ñ ÐºÐ°Ð½Ð°Ð»Ð¾Ð¼ в Ñамого
       ÑебÑ. Ð ÑÑом меÑоде обÑабоÑÑик Ñигнала пиÑеÑ
       Ð±Ð°Ð¹Ñ Ð² канал, Ñей вÑоÑой ÐºÐ¾Ð½ÐµÑ Ð¾ÑÑлеживаеÑÑÑ
       select() в оÑновной пÑогÑамме (ÑÑÐ¾Ð±Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ
       возможной блокиÑовки пÑи запиÑи в канал,
       коÑоÑÑй Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½, или пÑи ÑÑении
       из канала, коÑоÑÑй Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÑÑÑ, нÑжно
       иÑполÑзоваÑÑ Ð½ÐµÐ±Ð»Ð¾ÐºÐ¸ÑÑÑÑий ввод/вÑвод).

       Ð Linux, вÑзов select() Ð¼Ð¾Ð¶ÐµÑ ÑообÑаÑÑ Ð¾ Ñайловом
       деÑкÑипÑоÑе ÑокеÑа как о «гоÑовом длÑ
       ÑÑениÑ», ÑоÑÑ Ð¿Ñи поÑледÑÑÑем ÑÑении
       пÑоизойдÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовка. ÐÑо Ð¼Ð¾Ð¶ÐµÑ ÑлÑÑиÑÑÑÑ,
       напÑимеÑ, когда даннÑе пÑибÑли, но пÑи
       анализе Ð¸Ñ ÐºÐ¾Ð½ÑÑолÑÐ½Ð°Ñ ÑÑмма не Ñовпала и
       они бÑли оÑбÑоÑенÑ. Также могÑÑ Ð±ÑÑÑ Ð´ÑÑгие
       обÑÑоÑÑелÑÑÑва, пÑи коÑоÑÑÑ ÑайловÑй деÑкÑипÑоÑ
       оÑибоÑно ÑÑиÑаеÑÑÑ Ð³Ð¾ÑовÑм. ÐоÑÑомÑ, возможно
       безопаÑней бÑÐ´ÐµÑ Ð¸ÑполÑзоваÑÑ Ð´Ð»Ñ ÑокеÑов
       O_NONBLOCK, коÑоÑÑе не Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±Ð»Ð¾ÐºÐ¸ÑоваÑÑÑÑ.

       Ð Linux, вÑзов select() Ñакже изменÑÐµÑ timeout, еÑли
       он пÑеÑван обÑабоÑÑиком Ñигнала (Ñ. е.,
       возвÑаÑаеÑÑÑ Ð¾Ñибка EINTR). СоглаÑно POSIX.1 ÑÑо
       не ÑазÑеÑено. Ð Linux ÑиÑÑемнÑй вÑзов pselect()
       дейÑÑвÑÐµÑ Ñакже, но обÑÑÑка glibc ÑкÑÑÐ²Ð°ÐµÑ ÑÑо
       поведение копиÑÑÑ Ð¿ÐµÑед вÑзовом timeout в
       локалÑнÑÑ Ð¿ÐµÑеменнÑÑ Ð¸ пеÑÐµÐ´Ð°Ð²Ð°Ñ ÐµÑ Ð²
       ÑиÑÑемнÑй вÑзов.

ÐÐ ÐÐÐÐ
       #include <stdio.h>
       #include <stdlib.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 == -1)
               perror("select()");
           else if (retval)
               printf("ÐÑÑÑ Ð´Ð°Ð½Ð½Ñе.\n");
               /* FD_ISSET(0, &rfds) will be true. */
           else
               printf("ÐаннÑе не поÑвилиÑÑ Ð² ÑеÑение пÑÑи ÑекÑнд.\n");

           exit(EXIT_SUCCESS);
       }

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

       ÐбÑÑждение и пÑимеÑÑ ÑмоÑÑиÑе в select_tut(2).



Linux                             2016-03-15                         SELECT(2)