Frage

while (xxx) {
    timeout.tv_sec=TIMEOUT;
    timeout.tv_usec=0;
    FD_ZERO(&set); 
    FD_SET(sd,&set);

    switch (select(FD_SETSIZE,&set,NULL,NULL,&timeout))
    xxxxx
}

funktioniert gut, aber

FD_ZERO(&set); 
FD_SET(sd,&set);

while (xxx) {
    timeout.tv_sec=TIMEOUT;
    timeout.tv_usec=0;

    switch (select(FD_SETSIZE,&set,NULL,NULL,&timeout))
    xxxxx
}

nicht. Es funktioniert beim ersten Mal, aber das nächste Mal läuft es durch die while-Schleife es ein Timeout bekommt, auch wenn der SD-Buchse empfängt Daten. Es scheint mir, eine Verschwendung von Ressourcen zu haben, zu leeren und füllen Satz jedes Mal.

Wer eine gute Erklärung, warum dies ist, und noch besser, vielleicht einen Vorschlag, wie man es vermeiden?

War es hilfreich?

Lösung

select modifiziert seine Argumente. Sie wirklich tun müssen, um es jedes Mal neu zu initialisieren.

Wenn Sie über Kopf besorgt sind, die Kosten für die Verarbeitung der vollständigen FD_SET im Kernel ist etwas wichtiger als die Kosten für FD_ZERO. Sie würden wollen nur in Ihrer maximalen fd passieren, nicht FD_SETSZIZE, um die Kernel-Verarbeitung zu minimieren. In Ihrem Beispiel:

switch (select((sd + 1),&set,NULL,NULL,&timeout))

Für einen komplexere Fall mit mehreren fds, Sie in der Regel eine maximale Variable am Ende beibehalten:

FD_SET(sd,&set);
if (sd > max) max = sd;
... repeat many times...

switch (select((max + 1),&set,NULL,NULL,&timeout))


Wenn Sie eine große Anzahl von Datei-Deskriptoren haben und sind besorgt über den Overhead von schlepping ihnen über, sollten Sie auf einige der Alternativen zu suchen, um (zu wählen). Sie erwähnen nicht das Betriebssystem Sie verwenden, aber für Unix-ähnliche Betriebssysteme gibt es ein paar:

  • für Linux, epoll ()
  • für FreeBSD / NetBSD / OpenBSD / MacOS X, kqueue ()
  • für Solaris, / dev / poll

Die APIs sind unterschiedlich, aber sie sind alle im Wesentlichen eine Stateful-Kernel-Schnittstelle eine Reihe von aktiven Dateibeschreibungen zu halten. Sobald ein fd zu dem Satz hinzugefügt wird, werden Sie ohne auf diesem fd mitgeteilt Ereignisse werden, um sie kontinuierlich wieder passieren.

Andere Tipps

Lesen Sie die select-man-Seite. Die zurückgegebene Menge ist nur die Datei-Deskriptoren, die bereit sind, verwendet werden. Sie sollen FD_ISSET verwenden jeden zu überprüfen, ob es gesetzt ist oder nicht.

initialisieren immer die fd_set rechts bevor Sie es.

Das ist die Art und Weise ausgewählte Werke. Es funktioniert am besten, und macht mehr Sinn, wenn Sie mehr als eine Steckdose haben. Das ist irgendwie den Punkt: Sie über viele Steckdosen auswählen. Wenn Sie von einer Steckdose lesen, nur lesen oder empf.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top