Rechercher une page de manuel
select
Langue: pl
Version: 2001-02-09 (openSuse - 09/10/07)
Section: 2 (Appels système)
NAZWA
select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - synchroniczne zwielokratnianie we/wySK£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 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, const 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);
OPIS
Funkcje select i pselect oczekuj± na zmianê statusu pewnej liczby deskryptorów plików.Ich funkcjonalno¶æ 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 pselect 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 posiada 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, desktyptor 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± obserwowane 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.
Do obs³ugi tych zbiorów udostêpnone s± cztery makra: FD_ZERO czy¶ci zbiór. FD_SET i FD_CLR dodaj±, lub usuwaj± ze zbioru podany deskryptor. FD_ISSET sprawdza, czy deskryptor jest czê¶ci± zbioru. Jest to przydatne po zakoñczeniu select.
n jest nawy¿szym numerem deskryptora z wszystkich trzech zbiorów plus 1.
timeout jest górn± granic± czasu, który upynie 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 ksli 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 originaln± maskê sygna³ów.
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.) Poniewa¿ obecnie Linux nie posiada funkcji systemowej pselect(), aktualna procedura w glibc2 wci±¿ zawiera ryzyko takiego 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. 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 reinicjalizacji. Nale¿y traktowaæ timeout jako niezdefiniowany po zakoñczeniu select.
WARTO¦Æ ZWRACANA
Po pomy¶lnym zakoñczeniu, select i pselect zwracaj± liczbê deskryptorów w zbiorach deskryptorów. 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 podano nieprawid³owy deskryptor pliku.
- EINTR
- Przechwycono nieblokowany sygna³.
- EINVAL
- n jest ujemne lub warto¶æ timeout jest nieprawid³owa.
- ENOMEM
- select nie by³ w stanie 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¿ 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) printf("Dane s± ju¿ dostêpne.\n"); /* FD_ISSET(0, &rfds) bêdzie prawdziwy. */ else printf("Brak danych w ci±gu 5 sekund.\n"); exit(0); }
ZGODNE Z
4.4BSD (funkcja select pojawi³a siê pierwotnie w 4.2BSD). 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.Funkcja pselect jest zdefiniowana w IEEE Std 1003.1g-2000 (POSIX.1g) oraz czê¶ciowo w POSIX 1003.1-2001. Mo¿na j± znale¼æ w glibc2.1 i pó¼niejszych. Glibc2.0 zawiera funkcjê o tej samej nazwie, która jednak¿e, nie posiada parametru sigmask.
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 wybaga, by fd by³ prawid³owym deskryptorem pliku.Odno¶nie u¿ywanych typów, klasyczna sytuacja polega na tym, ¿e oba pola struktury struct 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 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, gdy 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.
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)
Contenus ©2006-2024 Benjamin Poulain
Design ©2006-2024 Maxime Vantorre