2009-03-13 3 views
6

select() wie folgt definiert ist:Abfrage auf Select System Call

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

nfds stellt den höchsten Dateideskriptor in allen angegebenen Mengen plus eins. Ich würde gerne wissen, warum diese Daten für select() benötigt werden, wenn die fd_set Informationen verfügbar sind.

Wenn die FDs im Satz sagen, 4, 8, 9, würde der Wert nfds 10 sein. Würde wählen() moniter fds 9,8,7,6,5,4?

Antwort

8

Der Haken ist, dass fd_set ist nicht wirklich ein "set" in der Art, wie Sie denken. Das Detail hinter den Kulissen ist, dass die Implementierung eines fd_set nur eine ganze Zahl ist, die als Bitfeld verwendet wird. Mit anderen Worten:

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

Sets foo Dezimalwert Ausführung 8 - stellt sie die viert wenigsten singificant Bit auf 1 (zur Erinnerung, dass 0 ein gültiger Deskriptor).

FD_SET(&foo, 3); 

entspricht

foo |= (1 << 3); 

Also, um für ausgewählte Recht auf Arbeit, muss er wissen, welche Bits des fd_set sind Bits, die Sie interessieren. Sonst würde es keine Möglichkeit geben, ein Null-Bit zu sagen, das in der Menge "in" ist, aber von einem Null-Bit, das "nicht in" der Menge ist, auf falsch gesetzt wird.

In Ihrem Beispiel wird ein fd_set mit 4, 8 und 9 gesetzt und n = 10 interpretiert als "Ein Set mit 10 Einträgen (Fds 0-9). Die Einträge 4, 8 und 9 sind wahr (überwachen Sie diese) Einträge 1, 2, 3, 5, 6, 7 sind falsch (nicht überwachen). Jeder fd Wert größer als 9 ist einfach nicht in der eingestellten Zeit. "

+1

Aber die Anzahl der Bits in Int ist 32, aber wie kann es jeden fd mit einem Wert größer als 31 überwachen – Poorna

+0

kann jemand diesen Kommentar beantworten? – euphoria83

+0

@Shishir: Posix definiert 'fd_set' als Struktur. Die Interna sind Implementierungen definiert, aber eine gängige Implementierung besteht darin, dass die Struktur ein Array von Longs mit genügend Bits im Array enthält, um alle möglichen fds abzudecken. Dies funktioniert, weil Posix auch "open" benötigt, um den unbenutzten Dateideskriptor mit der niedrigsten Nummer zurückzugeben. Sie werden also den Bereich des Arrays nur dann überschreiten, wenn FD_SETSIZE-Dateien geöffnet sind. http://pubs.opengroup.org/onlinepubs/007904975/basedefs/sys/select.h.html – indiv

0

Auswahl überwacht die FDs, die Sie mit dem Makro FD_SET aktiviert haben. Wenn Sie keine FD für die Überwachung aktivieren, wählen Sie() keine Überwachung aus.

"nfds" ist definitiv redundant, aber es ist Teil der select() Schnittstelle ist, so müssen Sie es verwenden :)

Wie auch immer, wenn Sie {4, 8, 9} in der Menge, Sie setzen Nfds auf 10 (wie Sie erwähnt), und wählen Sie() wird nur die drei FDs 4, 8 und 9 überwachen.

0

Es ist wahrscheinlich eine Optimierung, so dass select muss nicht durch die ganze fd_set zu finden gehen heraus, welche Deskriptoren tatsächlich verwendet werden. Ohne diesen Parameter müsste select immer den gesamten Satz betrachten, um herauszufinden, welche Deskriptoren tatsächlich in dem Aufruf verwendet werden, mit dem Parameter können einige dieser Arbeiten weggelassen werden.