2009-03-13 25 views
6

select() jest zdefiniowana jako:Zapytanie o wybrać System połączeń

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

nfds reprezentuje najwyższy deskryptor we wszystkich podanych zestawów plus jeden. Chciałbym wiedzieć, dlaczego te dane są wymagane dla select(), gdy dostępna jest informacja fd_set.

Jeśli FD w zestawie powiedzą, 4, 8, 9, wartość nfds będzie 10. Wybrał() moniter fds 9,8,7,6,5,4?

Odpowiedz

8

Połów jest taki, że fd_set nie jest tak naprawdę "zestawem" w sposobie myślenia. Szczegóły zza kulis są takie, że implementacja fd_set jest po prostu liczbą całkowitą używaną jako bitfield. Innymi słowy, wykonywanie

fd_set foo; 
FD_CLEAR(&foo); 
FD_SET(&foo, 3); 

Zestawy foo do wartości dziesiętnych 8 - ustawia czwartym najsłabiej singificant trochę do 1 (należy pamiętać, że 0 jest ważny deskryptor).

FD_SET(&foo, 3); 

jest równoważna

foo |= (1 << 3); 

Więc w celu wybierz prawo do pracy, musi wiedzieć, które bity fd_set są bity, które Cię interesują. W przeciwnym razie nie byłoby sposobu, aby powiedzieć bitowi zerowemu, że jest "w" zestawie, ale jest ustawione na false z bitu zerowego, który jest "nie w" zestawie.

W twoim przykładzie zestaw fd_set z ustawieniami 4, 8 i 9 oraz n = 10 jest interpretowany jako "Zbiór z 10 wpisami (fds 0-9). Wpisy 4, 8 i 9 są prawdziwe (monitoruj je Wpisy 1,2,3,5,6,7 są fałszywe (nie monitoruj ich) Każda wartość fd większa niż 9 jest po prostu nie w ustawionym okresie. "

+1

Ale liczba bitów w int wynosi 32, ale jak może monitorować dowolny plik fd o wartości większej niż 31 – Poorna

+0

Czy ktoś może odpowiedzieć na ten komentarz? – euphoria83

+0

@Shishir: Posix definiuje 'fd_set' jako strukturę. Wewnętrzne implementacje są zdefiniowane, ale popularną implementacją jest to, że struktura zawiera tablicę longów z wystarczającą liczbą bitów w tablicy, aby objąć wszystkie możliwe fd. Działa to, ponieważ Posix wymaga również "otwartego", aby zwrócić "najniższy ponumerowany nieużywany deskryptor pliku". Więc nie przekroczysz zakresu tablicy, chyba że masz otwarte pliki FD_SETSIZE. http://pubs.opengroup.org/onlinepubs/007904975/basedefs/sys/select.h.html – indiv

0

Wybierz monitoruje te FD, które zostały włączone przy użyciu makra FD_SET. Jeśli nie włączysz żadnego FD do monitorowania, select() nie monitoruje żadnych.

"nfds" jest zdecydowanie zbędny, ale jest częścią select() interfejsu, więc trzeba go :)

użyć W każdym razie, jeśli masz {4, 8, 9} w zbiorze, ustawić nfds do 10 (jak wspomniano) i select() monitoruje tylko trzy FD 4, 8 i 9.

0

To chyba tak, że optymalizacja select nie trzeba chodzić przez cały fd_set znaleźć które z deskryptorów są faktycznie używane. Bez tego parametru, select zawsze musiałby przyjrzeć się całemu zestawowi, aby znaleźć, które deskryptory są faktycznie używane w wywołaniu, z parametrem niektóre z tych prac można pominąć.