Linux.pl
Opcje wyszukiwania podręcznika man:
Lista stron man zaczynających się od znaku:
A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P   Q   R   S   T   U   V   W   X   Y   Z   ALPHA   NUM   OTHER   ALL
SELECT(2)               Podręcznik programisty Linuksa               SELECT(2)

NAZWA
       select,  pselect,  FD_CLR,  FD_ISSET,  FD_SET,  FD_ZERO - synchroniczne
       zwielokratnianie we/wy

SKŁADNIA
       /* Zgodnie z POSIX 1003.1-2001 */
       #include <sys/select.h>

       /* Zgodnie z wcześniejszymi standardami */
       #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);

       #define _XOPEN_SOURCE 600
       #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);

OPIS
       select()  i  pselect()  umożliwiają  programowi   monitorowanie   wielu
       deskryptorów  plików  i  oczekiwanie  aż  jeden lub więcej deskryptorów
       będzie "gotowy" na wykonanie pewnej klasy operacji wejścia/wyjścia (np.
       możliwy  odczyt).  Deskryptor  pliku  jest  uważany  za  gotowy, jeżeli
       możliwe  jest  wykonanie  odpowiadającej  operacji  (np.  read(2))  bez
       blokowania.

       Funkcjonalność  funkcji  select()  i  pselect()  jest identyczna, jeśli
       pominąć trzy różnice:

       (i)    Funkcja select() używa czasu parametru timeout, który jest  typu
              struct  timeval (z sekundami i mikrosekundami), podczas gdy pse-
              lect() używa typu struct timespec (z sekundami i nanosekundami).

       (ii)   Funkcja   select()   może  aktualizować  parametr  timeout,  aby
              wskazać, jak dużo czasu minęło. Funkcja  pselect()  nie  zmienia
              tego parametru.

       (iii)  Funkcja  select()  nie  przykmuje  parametru sigmask i zachowuje
              się, jak pselect() wywołane z NULL sigmask.

       Podglądane są  trzy  niezależne  zestawy  deskryptorów.  Te,  które  są
       wymienione  w  readfds będą obserwowane w celu dowiedzenia się, czy nie
       ma  tam  jakichś  znaków  dostępnych  do  czytania   (dokładniej,   aby
       dowiedzieć  się,  czy read nie spowoduje zablokowania, deskryptor pliku
       jest również przygotowany na koniec pliku).  Deskryptory  wymienione  w
       writefds  będą  obserwowane  w  celu  dowiedzenia  się,  czy  zapis nie
       spowoduje blokady, a deskryptory wymienione  w  exceptfds  będą  obser-
       wowane  w  celu  dowiedzenia  się,  czy  nie  ma  na nich wyjątku. Przy
       wyjściu, zbiory te są modyfikowane,  wskazując,  które  z  deskryptorów
       zmieniły  status.  Każdy z tych trzech zbiorów deskryptorów plików może
       być przekazany jako NULL, jeżeli dla żadnego deskryptora  pliku  na  ma
       potrzeby obserwowania odpowiedniej klasy zdarzeń.

       Do  obsługi tych zbiorów udostępnione są cztery makra: FD_ZERO() czyści
       zbiór. FD_SET() i FD_CLR() dodają lub usuwają ze zbioru podany deskryp-
       tor.  FD_ISSET()  sprawdza, czy deskryptor jest częścią zbioru. Jest to
       przydatne po zakończeniu select().

       nfds jest najwyższym numerem deskryptora z  wszystkich  trzech  zbiorów
       plus 1.

       timeout  jest  górną  granicą  czasu,  który upłynie przed zakończeniem
       działania  funkcji  select().  Gdy  przyjmie  wartość  zero,   select()
       zakończy  pracę  natychmiast. (Jest to przydatne w uwspólnianiu). Jeśli
       timeout jest równe NULL (brak czasu  przeterminowania),  select()  może
       blokować w nieskończoność.

       sigmask  jest  wskaźnikiem  do  maski sygnałów (zobacz sigprocmask(2)).
       Jeśli nie jest równe NULL,  to  pselect()  najpierw  zastępuje  bieżącą
       maskę  sygnałów  maską  wskazywaną  przez sigmask, a następnie wywołuje
       funkcję `select' i ponownie odtwarza oryginalną maskę sygnałów.

       Poza różnicą w precyzji argumentu timeout, następujące  wywołanie  pse-
       lect():

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

       jest odpowiednikiem niepodzielnego wykonania następujących funkcji:

           sigset_t origmask;

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

       Idea  pselect()  polega  na tym, że gdy chce się oczekiwać na zdarzenie
       będące sygnałem lub czymś na deskryptorze pliku, potrzebny jest atomowy
       test zapobiegający sytuacjom wyścigu. (Przypuśćmy, że procedura obsługi
       sygnału ustawia globalny znacznik i  kończy  działanie.  Wówczas,  test
       tego  znacznika globalnego, po którym następuje wywołanie select() może
       wisieć w nieskończoność, gdyby sygnał przybył  natychmiast  po  teście,
       ale  przed  wywołaniem.  Inaczej  mówiąc, pselect zezwala na, najpierw,
       zablokowanie sygnałów, następnie obsłużenie dostarczonych sygnałów, aby
       wreszcie wywołać pselect() z pożądanym sigmask, unikając wyścigu).

   Przeterminowanie
       Struktury  czasu,  których to dotyczy, są zdefiniowane w <sys/time.h> i
       wyglądają następująco

         struct timeval {
             long    tv_sec;         /* sekundy */
             long    tv_usec;        /* mikrosekundy */
         };

       i

         struct timespec {
             long    tv_sec;         /* sekundy */
             long    tv_nsec;        /* nanosekundy */
         };

       (Jednakże odnośnie wersji POSIX 1003.1-2001 zobacz poniżej).

       Niektóre  programy  wywołują  select()  z  wszystkimi  trzema  zbiorami
       pustymi,  z  n  równym  zeru  i  niezerowym  timeout.  Jest  to całkiem
       przenośny sposób pauzowania z dokładnością subsekundową.

       Pod Linuksem funkcja select() modyfikuje  timeout,  aby  odzwierciedlić
       ilość  nieprzespanego  czasu;  większość  innych implementacji tego nie
       robi (POSIX.1-2001 dopuszcza oba te zachowania). Powoduje to  problemy,
       zarówno  gdy kod linuksowy odczytujący timeout zostanie przeniesiony na
       inne systemy operacyjne, jak i  gdy  kod  przeniesiony  pod  Linuksa  z
       innych  systemów  używa  ponownie struct timeval dla wielu select()ów w
       pętli,  bez  powtórnej  inicjacji.  Należy   traktować   timeout   jako
       niezdefiniowany po zakończeniu select().

WARTOŚĆ ZWRACANA
       Po pomyślnym zakończeniu, select() i pselect() zwracają liczbę deskryp-
       torów w zbiorach deskryptorów (to jest całkowitę liczbę bitów ustawioną
       w  readfds,  writefds,  exceptfds).  Może ona być zerowa, jeśli nastąpi
       przeterminowanie, nim coś ciekawego się zdarzy.  Po  błędzie,  zwracane
       jest  -1  i  odpowiednio ustawiane errno; zbiory deskryptorów i timeout
       stają się niezdefiniowane, więc nie należy polegać na ich zawartości.

BŁĘDY
       EBADF  W jednym ze zbiorów przekazano niepoprawny deskryptor pliku (Być
              może  deskryptor  ten  został  już zamknięty lub wystąpił na nim
              inny błąd).

       EINTR  Przechwycono sygnał.

       EINVAL nfds jest ujemne lub wartość timeout jest nieprawidłowa.

       ENOMEM nie można było przydzielić pamięci dla wewnętrznych tablic.

PRZYKŁAD
       #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;

           /* Obserwacja stdin (fd 0) i sprawdzanie kiedy ma wejście. */
           FD_ZERO(&rfds);
           FD_SET(0, &rfds);

           /* Czekanie nie dłużej niż 5 sekund. */
           tv.tv_sec = 5;
           tv.tv_usec = 0;

           retval = select(1, &rfds, NULL, NULL, &tv);
           /* Nie należy już polegać na wartości tv! */

           if (retval == -1)
               perror("select()");
           else if (retval)
               printf("Dane są już dostępne.\n");
               /* FD_ISSET(0, &rfds) będzie prawdziwy. */
           else
               printf("Brak danych w ciągu 5 sekund.\n");

           return 0;
       }

ZGODNE Z
       BSD 4.4 (funkcja  select()  pojawiła  się  pierwotnie  w  BSD  4.2).  W
       ogólności  przenośne  do/z  systemów  nie-BSD  wspierających sklonowaną
       warstwę gniazd BSD (włączając warianty  Systemu  V).  Jednakże,  należy
       zauważyć,  że  warianty  Systemu V zasadniczo ustawiają zmienną timeout
       przed zakończeniem, ale wariant BSD tego nie robi.

       pselect() jest zdefiniowany w IEEE  Std  1003.1g-2000  (POSIX.1g)  i  w
       POSIX 1003.1-2001.

UWAGI
       fd_set jest buforem o stałym rozmiarze. Wykonanie FD_CLR() lub FD_SET()
       z ujemną wartością fd albo z wartością  większą  lub  równą  FD_SETSIZE
       spowoduje  zachowanie  niezdefiniowane. Ponadto POSIX wymaga, by fd był
       prawidłowym deskryptorem pliku.

       Odnośnie używanych typów, klasyczna sytuacja polega na tym, że oba pola
       struktury timeval są typu long (jak pokazano powyżej), a sama struktura
       jest zdefiniowana w <sys/time.h>. W  POSIX  1003.1-2001  sytuacja  jest
       następująca

              struct timeval {
                  time_t         tv_sec;     /* sekundy */
                  suseconds_t    tv_usec;    /* mikrosekundy */
              };

       przy czym struktura jest zdefiniowana w <sys/select.h>, a typy time_t i
       suseconds_t zdefiniowano w <sys/types.h>.

       Odnośnie do prototypów,  klasyczna  sytuacja  polega  na  tym,  że  dla
       select()  należy  włączyć <time.h>. Sytuacja z POSIX 1003.1-2001 polega
       na tym, że dla select()  i  pselect()  należy  włączyć  <sys/select.h>.
       libc4  i libc5 nie zawierają pliku nagłówkowego <sys/select.h>; w glibc
       2.0 i późniejszymi ten plik nagłówkowy istnieje. W glibc 2.0 udostępnia
       on  bezwarunkowo  błędny  prototyp  dla  pselect().  W  glibc 2.1-2.2.1
       udostępnia on pselect(), jeżeli zdefiniowane jest _GNU_SOURCE. W  glibc
       2.2.2-2.2.4    udostępnia   go   natomiast,   gdy   zdefiniowane   jest
       _XOPEN_SOURCE i ma wartość 600 lub większą. Niewątpliwie, począwszy  od
       POSIX 1003.1-2001 plik ten powinien udostępniać prototyp standardowo.

WERSJE
       pselect() został dodany do jadra Linuksa 2.6.16.

       Wcześniej  pselect()  był emulowany w glibc (patrz również BŁĘDY IMPLE-
       MENTACJI).

UWAGI LINUKSOWE
       Wywołanie systemowa pselect() pod Linuksem modyfikuje argument timeout.
       Jednakże  funkcja glibc ukrywa to zachowanie przez użycie dla argumentu
       timeout lokalnej zmiennej, która jest przekazywana do wywołania  syste-
       mowego.  Dlatego  pselect()  z  glibc nie zmienia argumentu timeout, co
       jest zachowaniem wymaganym przez POSIX.1-2001.

BŁĘDY IMPLEMENTACJI
       Glibc 2.0 dostarczała wersję pselect(), która nie przyjmowała argumentu
       sigmask.

       Od  wersji 2.1 glibc dostarczał emulację pselect(), która była zaimple-
       mentowana przy  użyciu  sigprocmask(2)  i  select().  Implementacja  ta
       pozostaje  podatna  na wiele błędów wyścigów (race conditions), których
       uniknięcie stanowiło ideę funkcji pselect().  W  systemach,  które  nie
       mają   pselect()  niezawodne  (i  bardziej  przenośne)  przechwytywanie
       sygnałów można osiągnąć, używając triku potoku do siebie (gdzie  proce-
       dura obsługi sygnału zapisuje bajt do potoku, którego drugi koniec jest
       monitorowany przez select() w głównym programie).

       Pod Linuksem select() może raportować deskryptory  plików  gniazd  jako
       "dostępne   do   czytania",   podczas   gdy  kolejne  czytania  zostaną
       zablokowane. Może to się zdarzyć na przykład wtedy, gdy dane  nadeszły,
       ale  podczas  sprawdzania  okazało  się,  że  mają złą sumę kontrolną i
       zostały  odrzucone.  Mogą  wystąpić  także  inne  sytuacje,  w  których
       deskryptor pliku jest błędnie raportowany jako gotowy. Dlatego używanie
       O_NONBLOCK na gniazdach, które nie powinny się blokować może  być  bez-
       pieczniejsze.

ZOBACZ TAKŻE
       Samouczek z dyskusją i przykładami znajduje się w select_tut(2).

       Rzeczy w nieokreślony sposób powiązane z tym można znaleźć w accept(2),
       connect(2),  poll(2),  read(2),   recv(2),   send(2),   sigprocmask(2),
       write(2), epoll(7), feature_test_macros(7)

Linux 2.6.16                      2006-03-11                         SELECT(2)

Time taken: 0.00037 seconds


Created with the man page lookup class by Andrew Collington, php@amnuts.com