Provided by: manpages-de-dev_2.5-1_all bug

BEZEICHNUNG

       select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - synchrones E/A-Zeitmultiplexverfahren

ÜBERSICHT

       /* laut POSIX.1-2001, POSIX.1-2008 */
       #include <sys/select.h>

       /* Laut älterer Standards */
       #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);

       #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);

   Mit Glibc erforderliche Makros (siehe feature_test_macros(7)):

       pselect(): _POSIX_C_SOURCE >= 200112L

BESCHREIBUNG

       Mit  den  Funktionen  select()  und  pselect() kann ein Programm mehrere Dateideskriptoren überwachen und
       warten, bis ein oder mehrere der Dateideskriptoren »bereit« für eine Klasse von E/A-Aktionen sind  (z. B.
       Eingabe  möglich).  Ein  Dateideskriptor  gilt  als  bereit,  wenn  es  möglich  ist,  eine entsprechende
       E/A-Aktionen (z.B. read (2) ohne zu blockieren oder ein hinreichend kleines write(2)) durchzuführen.

       select() kann nur Dateideskriptorennummern überwachen, die kleiner als FD_SETSIZE sind; poll(2) hat diese
       Einschränkung nicht. Siehe FEHLER.

       Das Verhalten von select() und pselect() ist bis die folgenden drei Unterschiede identisch:

       (i)    select()  verwendet  für  Zeitbegrenzungen  (timeouts)  eine  struct  timeval  (mit  Sekunden  und
              Mikrosekunden), während pselect() stattdessen eine struct timespec (mit Sekunden und Nanosekunden)
              verwendet.

       (ii)   Während  select()  das Argument timeout ändern darf, um die verbleibende Zeit anzugeben, verändert
              pselect() dieses Argument nicht.

       (iii)  Die Funktion select() hat keinen Parameter sigmask und verhält sich  wie  pselect,  wenn  ihr  für
              sigmask ein NULL-Zeiger übergeben wird.

       Es  werden  drei  voneinander  unabhängige Mengen von Deskriptoren überwacht. Die in readfds aufgeführten
       Deskriptoren werden daraufhin beobachtet, ob neue Zeichen zum Lesen ankommen (genauer: ob eine Leseaktion
       nicht   blockiert;   insbesondere   ist   ein  Dateideskriptor  auch  am  Dateiende  (EOF)  bereit).  Die
       Datei-Deskriptoren in writefds werden daraufhin beobachtet, ob Platz zum  Schreiben  verfügbar  ist  (ein
       größerer  Schreibaufruf  kann aber dennoch blockieren) und die Datei-Deskriptoren in exceptfds werden auf
       außergewöhnliche Bedingungen überwacht. (Lesen Sie die Diskussion von POLLPRI in  poll(2)  für  Beispiele
       für außergewöhnliche Bedingungen.)

       Wenn  die  Funktion beendet wird, wird jede der Datei-Deskriptorenmengen so verändert, dass sie anzeigen,
       welcher Deskriptor seinen Status geändert  hat.  (Falls  Sie  daher  select()  innerhalb  einer  Schleife
       verwenden, müssen die Mengen vor jedem Aufruf neu initialisiert werden.)

       Jeder  der  drei  Mengen  von  Deskriptoren  kann als NULL angegeben werden, falls für die entsprechenden
       Dateideskriptoren keine Klassen oder Ereignisse überwacht werden müssen.

       Es werden vier Makros bereitgestellt, um mit diesen Mengen zu  arbeiten.  FD_ZERO()  löscht  eine  Menge,
       FD_SET()  fügt einen Deskriptor zu einer Menge hinzu und FD_CLR() löscht diesen. FD_ISSET() prüft, ob der
       Deskriptor in der Menge enthalten ist. Das ist insbesondere nach einem Aufruf von select() nützlich.

       nfds sollte auf die Nummer des am höchsten nummerierten Dateideskriptors in  allen  drei  Mengen  plus  1
       gesetzt  werden.  Der  gekennzeichnete  Dateideskriptor  in  jeder  der  drei  Mengen  wird bis zu dieser
       Begrenzung geprüft (siehe aber FEHLER).

       Das Argument timeout legt das Intervall fest, das select() warten sollte, bis ein Dateideskriptor  bereit
       wird. Der Aufruf wird blockieren, bis entweder:

       *  ein Dateideskriptor bereit wird,

       *  der Aufruf durch einen Signal-Handler unterbrochen wird, oder

       *  die Wartezeit (timeout) abläuft.

       Beachten  Sie,  das  das  Intervall  timeout  auf  die  Auflösung  der  Systemuhr aufgerundet wird. Durch
       Verzögerungen beim Kernel-Scheduling kann dieser Wert nochmals etwas größer werden.  Falls  beide  Felder
       der  Struktur  timeval  gleich  null sind, kehrt select() sofort zurück. (Das ist praktisch für Polling).
       Falls timeout gleich NULL ist (kein timeout), kann select() auf unbestimmte Zeit blockieren.

       sigmask ist ein Zeiger auf eine Signalmaske (siehe sigprocmask(2)); falls er ungleich NULL  ist,  ersetzt
       pselect()  zuerst  die  aktuelle  Signalmaske  mit derjenigen, auf die sigmask weist, erledigt danach die
       »select«-Funktion und stellt als Letztes die ursprüngliche Signalmaske wieder her.

       Abgesehen von der unterschiedlichen Genauigkeit des timeout-Arguments ist der pselect()-Aufruf

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

       äquivalent zur atomaren (unterbrechungsfreien, aufeinanderfolgenden) Ausführung der folgenden Aufrufe:

           sigset_t origmask;

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

       Falls man auf die Verfügbarkeit  eines  Signals  oder  eines  Dateideskriptors  warten  möchte,  ist  zur
       Vermeidung von Wettlaufsituationen (race conditions) eine atomare Prüfung erforderlich, die von pselect()
       erledigt wird. (Angenommen, der Signal Handler setzt einen  globalen  Schalter  und  kehrt  zurück.  Dann
       könnte  eine Prüfung dieses globalen Schalters gefolgt von einem Aufruf von select() auf unbestimmte Zeit
       hängen, wenn das Signal zwischen der Prüfung und vor dem Aufruf von select() eintrifft. Im Gegensatz dazu
       ermöglicht  es  pselect()  zuerst  Signale  zu  blockieren,  die  eingetroffenen Signale abzuarbeiten und
       anschließend pselect() mit der gewünschten sigmask aufzurufen, um Race Conditions zu vermeiden.)

   Die Wartezeit (timeout)
       Die Zeitstrukturen sind in <sys/time.h> als

           struct timeval {
               long    tv_sec;         /* Sekunden */
               long    tv_usec;        /* Mikrosekunden */
           };

       und

           struct timespec {
               long    tv_sec;         /* Sekunden */
               long    tv_nsec;        /* Nanosekunden */
           };

       definiert. (Sehen Sie sich aber weiter unten die Besonderheiten der POSIX.1-Versionen an.)

       Es gibt Code, der select wie folgt aufruft: alle drei Deskriptor-Mengen leer, nfds gleich  null  und  ein
       von  NULL  verschiedenes  timeout  als recht portabler Weg, um mit Auflösungen unterhalb einer Sekunde zu
       schlafen.

       Unter Linux modifiziert select() timeout, um die nicht schlafend verbrachte Zeit anzuzeigen; die  meisten
       anderen  Implementierungen tun das nicht. (POSIX.1 lässt beiderlei Verhalten zu.) Dies führt zu Problemen
       sowohl bei der Portierung von Linux-Code, der timeout liest, auf andere Betriebssysteme als auch bei  der
       Portierung  von  Code  nach  Linux,  der  eine struct timeval in einer Schleife für mehrfache Aufrufe von
       select() nutzt, ohne sie erneut zu initialisieren. Gehen Sie davon aus, dass timeout  nach  der  Rückkehr
       aus select() nicht definiert ist.

RÜCKGABEWERT

       Bei  Erfolg  geben  select()  und pselect() die Anzahl der Datei-Deskriptoren in den drei zurückgegebenen
       Deskriptor-Mengen zurück. (Das entspricht der Gesamtzahl von Bits, die in readfds, writefds und exceptfds
       gesetzt  sind.)  Der Wert kann null sein, falls die Wartezeit abläuft, ohne das irgendetwas von Bedeutung
       geschieht. Wenn ein Fehler auftritt, wird -1 zurückgegeben und errno gesetzt, um  den  Fehler  anzugeben.
       Die Datei-Deskriptor-Mengen bleiben unverändert und timeout wird undefiniert.

FEHLER

       EBADF  In  einem  der Mengen wurde ein ungültiger Dateideskriptor angegeben. (Vielleicht war es ein schon
              geschlossener Dateideskriptor oder einer, bei dem ein Fehler aufgetreten ist.) Lesen Sie aber auch
              FEHLER.

       EINTR  Ein Signal wurde abgefangen; siehe signal(7).

       EINVAL nfds ist negativ oder übersteigt die Ressourcenbegrenzung RLIMIT_NOFILE (siehe getrlimit(2)).

       EINVAL Der Wert von timeout ist ungültig.

       ENOMEM Speicher für interne Tabellen konnte nicht bereitgestellt werden.

VERSIONEN

       pselect()  wurde  im Linux-Kernel 2.6.16 hinzugefügt. Vorher wurde pselect() in der Glibc emuliert (siehe
       aber FEHLER).

KONFORM ZU

       select() erfüllt POSIX.1-2001, POSIX.1-2008 und  4.4BSD  (select()  erschien  erstmalig  in  4.2BSD).  Im
       Allgemeinen von/nach nicht BSD-Systeme portabel, unterstützt Klone der BSD-Socket-Schicht (einschließlich
       System-V-Varianten).  Beachten  Sie  allerdings,  dass  System-V-Varianten  typischerweise  die  Variable
       »timeout« vor dem Beenden setzen, die BSD-Variante aber nicht.

       pselect() ist in POSIX.1g und in POSIX.1-2001 und in POSIX.1-2008 definiert.

ANMERKUNGEN

       Ein  fd_set  ist ein Puffer fester Größe. Wird FD_CLR() oder FD_SET() mit einem Wert für fd, der negativ,
       gleich groß oder größer als FD_SETSIZE ist,  ausgeführt,  führt  dies  zu  nicht  definiertem  Verhalten.
       Desweiteren verlangt POSIX, dass fd ein gültiger Dateideskriptor ist.

       Unter  einigen  UNIX-Systemen kann select() mit dem Fehler EAGAIN fehlschlagen, falls es dem System nicht
       gelingt, Kernel-interne Ressourcen zuzuweisen. Linux verwendet hierbei ENOMEM. POSIX legt  diesen  Fehler
       für  poll(2) aber nicht für select() fest. Portable Anwendungen könnten in einer Schleife auf EAGAIN (wie
       auch auf EINTR) prüfen.

       Auf Systemen, auf denen pselect() fehlt, kann ein zuverlässiges (und portableres) Abfangen  von  Signalen
       mit  dem  Selbst-Pipe-Trick  erreicht  werden. Bei dieser Technik schreibt ein Signal-Handler ein Byte in
       eine Pipe, dessen anderes Ende von select() im Hauptprogramm überwacht  wird.  (Um  mögliches  Blockieren
       beim  Schreiben  in  eine Pipe, die voll sein könnte, oder Lesen aus einer Pipe, die leer sein könnte, zu
       vermeiden, wird nicht blockierende E/A beim Auslesen und Schreiben in die Pipe verwandt.)

       Im Hinblick auf die beteiligten Typen ist die klassische  Situation,  dass  zwei  Felder  einer  Struktur
       timeval  vom  Typ  long  (wie  gezeigt)  sind  und  die  Struktur  in  <sys/time.h>  definiert  ist.  Die
       POSIX.1-Situation ist

           struct timeval {
               time_t         tv_sec;     /* Sekunden */
               suseconds_t    tv_usec;    /* Mikrosekunden */
           };

       wobei die Struktur in <sys/select.h> definiert und die Datentypen time_t und suseconds_t in <sys/types.h>
       definiert sind.

       Im  Hinblick  auf  Prototypen ist die klassische Situation, dass <time.h> für select() eingebunden werden
       sollte. Die Situation unter POSIX.1 ist, dass  <sys/select.h>  für  select()  und  pselect()  eingebunden
       werden sollte.

       Unter  Glibc  2.0 gibt <sys/select.h> den falschen Prototyp für pselect(). Unter Glibc 2.1 bis 2.2.1 gibt
       er pselect(), wenn _GNU_SOURCE definiert  ist.  Seit  Glibc  2.2.2  gelten  die  in  ÜBERSICHT  gezeigten
       Anforderungen.

   Korrespondenz zwischen den Benachrichtigungen select() und poll()
       Innerhalb  der Linux-Kernelquellen finden wir die folgende Definition, die die Korrespondenz zwischen den
       lesbaren, schreibbaren und  außerordentlichen  Zustandsbenachrichtigungen  von  select()  und  den  durch
       poll(2) (und epoll(7)) bereitgestellten Ereignisbenachrichtigungen zeigt:

           #define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP |
                               POLLERR)
                              /* Bereit zum Lesen */
           #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
                              /* Bereit zum Schreiben */
           #define POLLEX_SET (POLLPRI)
                              /* Außergewöhnliche Bedingung */

   Multithreaded Anwendungen
       Falls  ein  Dateideskriptor, der durch select() überwacht wird, in einem anderen Thread geschlossen wird,
       ist das Ergebnis nicht spezifiziert. Auf einigen UNIX-Systemen entblockt select()  und  kehrt  mit  einer
       Information zurück, dass der Dateideskriptor bereit ist (eine nachfolgende E/A-Aktion wird wahrscheinlich
       mit einem Fehler fehlschlagen, außer jemand anders hat den Dateideskriptor zwischen dem Zeitpunkt, zu dem
       select()  zurückkehrte, und dem Zeitpunkt, zu der die E/A-Aktion stattfand, wieder geöffnet). Unter Linux
       (und einigen anderen Systemen) hat das Schließen des Dateideskriptors  in  einem  anderen  Thread  keinen
       Effekt  auf  select().  Zusammenfassend  sollte  jede Anwendung, die sich auf ein bestimmtes Verhalten in
       diesem Szenario abstützt, als fehlerhaft betrachtet werden.

   Unterschiede C-Bibliothek/Kernel
       Der Linux-Kernel erlaubt Dateideskriptormengen beliebiger Größe und bestimmt die Größe der  zu  prüfenden
       Mengen  durch  den  Wert  von nfds. In der Glibc-Implementierung ist der Typ fd_set allerdings von fester
       Größe. Siehe auch FEHLER.

       Die in dieser Seite  beschriebene  Schnittstelle  von  pselect()  wird  durch  Glibc  implementiert.  Der
       darunterliegende  Systemaufruf  heißt pselect6(). Dieser Systemaufruf hat ein etwas anderes Verhalten als
       die Glibc-Wrapper-Funktion.

       Der Systemaufruf  pselect6()  von  Linux  verändert  das  Argument  timeout.  Die  Glibc-Wrapper-Funktion
       versteckt  dieses  Verhalten  durch Verwendung einer lokalen Variablen für das Arguemnt »timeout«, die an
       den Systemaufruf übergeben wird. Daher verändert die Glibc-Funktion pselect() nicht ihr Argument timeout;
       dies ist das von POSIX.1-2001 verlangte Verhalten.

       Das  finale  Argument  des Systemaufrufs pselect6() ist kein sigset_t *-Zeiger, sondern eine Struktur der
       folgenden Form:

           struct {
               const kernel_sigset_t *ss;  /* Zeiger auf Signalgruppe */
               size_t ss_len;              /* Größe (in Bytes) des Objekts,
                                              auf das durch »ss« gezeigt wird */
           };

       Dies erlaubt es dem Systemaufruf, sowohl einen Zeiger auf  die  Signalgruppe  als  auch  seine  Größe  zu
       ermitteln  und  dabei  zu  berücksichtigen,  dass  die  meisten  Architekturen eine maximale Anzahl von 6
       Argumenten für einen Systemaufruf erlauben. Siehe sigprocmask(2) für  eine  Diskussion  der  Unterschiede
       zwischen der Ansicht des Kernels und der Ansicht der Libc bezüglich der Singalmenge.

FEHLER

       POSIX erlaubt einer Implementierung, eine oberer Begrenzung für den Bereich von Dateideskriptoren, die in
       einer Dateideskriptorenmenge festgelegt werden können, zu definieren. Diese Begrenzung soll  mittels  der
       Konstanten  FD_SETSIZE bekannt gemacht werden. Der Linux-Kernel erzwingt keine feste Begrenzung, aber die
       Glibc-Implementierung macht fd_set zu einem Typ fester Größe, wobei FD_SETSIZE als 1024 definiert ist und
       die  Makros  FD_*()  arbeiten  entsprechend  dieser  Begrenzung.  Um Dateideskriptoren größer als 1024 zu
       überwachen verwenden Sie stattdessen poll(2).

       Laut POSIX sollte select() alle festgelegten Dateideskriptoren in den  drei  Dateideskriptorenmengen  bis
       zur  Grenze  nfds-1  prüfen.  Allerdings  ignoriert die aktuelle Implementierung jeden Dateideskriptor in
       diesen Mengen, der größer als die maximale Dateideskriptorennummer ist, die  der  Prozess  derzeit  offen
       hat.  Laut  POSIX sollte jeder solcher Dateideskriptoren, der in einem der drei Mengen festgelegt ist, zu
       einem Fehler EBADF führen.

       Glibc 2.0 stellte eine Version von pselect() bereit, die das Argument sigmask nicht akzeptierte.

       Beginnend mit Version 2.1 stellt Glibc eine Emulation von pselect() bereit,  die  mittels  sigprocmask(2)
       und  select()  implementiert  wurde.  Diese  Implementierung  blieb  für  den  starken Ressourcenwettlauf
       verwundbar, der durch das Design von pselect() vermieden  werden  sollte.  Moderne  Versionen  der  Glibc
       verwenden den (ressourcenwettlauffreien) pselect()-Systemaufruf auf Kerneln, die ihn bereitstellen.

       Unter  Linux  könnte select() einen Socket-Dateideskriptor als »bereit zum Lesen« melden, obwohl trotzdem
       ein folgendes Lesen blockiert. Dies könnte beispielsweise passieren, wenn Daten angekommen sind, aber bei
       genauerer  Prüfung  die falsche Prüfsumme haben und daher verworfen werden. Es mag andere Umstände geben,
       in denen ein Dateideskriptor fälschlicherweise als bereit berichtet werden könnte. Daher mag es  sicherer
       sein, O_NONBLOCK bei Sockets zu benutzen, die nicht blockieren sollen.

       Unter  Linux  verändert select() auch timeout falls der Aufruf durch ein Signal-Handler unterbrochen wird
       (d.h. den Fehler EINTR zurückliefert). Dies  wird  von  POSIX.1  nicht  erlaubt.  Der  Linux-Systemaufruf
       pselect()  zeigt  das  gleiche Verhalten, aber der Glibc-Wrapper versteckt das Verhalten, indem er intern
       timeout in eine lokale Variable kopiert und diese Variable an den Systemaufruf übergibt.

BEISPIEL

       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/time.h>
       #include <sys/types.h>
       #include <unistd.h>

       int
       main(void)
       {
           fd_set rfds;
           struct timeval tv;
           int retval;

           /* Beobachte stdin (fd 0), um zu sehen, wenn es Eingaben gibt. */

           FD_ZERO(&rfds);
           FD_SET(0, &rfds);

           /* Warte bis zu fünf Sekunden. */

           tv.tv_sec = 5;
           tv.tv_usec = 0;

           retval = select(1, &rfds, NULL, NULL, &tv);
           /* Verlassen Sie sich jetzt nicht auf den Wert von tv! */

           if (retval == -1)
               perror("select()");
           else if (retval)
               printf("Daten sind jetzt verfügbar.\n");
               /* FD_ISSET(0, &rfds) werden wahr sein. */
           else
               printf("Innerhalb von fünf Sekunden keine Daten.\n");

           exit(EXIT_SUCCESS);
       }

SIEHE AUCH

       accept(2), connect(2), poll(2), read(2), recv(2), restart_syscall(2), send(2), sigprocmask(2),  write(2),
       epoll(7), time(7)

       Für eine Anleitung mit Diskussionen und Beispielen lesen Sie select_tut(2).

KOLOPHON

       Diese  Seite  ist  Teil  der  Veröffentlichung  4.15  des Projekts Linux-man-pages. Eine Beschreibung des
       Projekts, Informationen, wie Fehler gemeldet werden können sowie die aktuelle Version dieser Seite finden
       sich unter https://www.kernel.org/doc/man-pages/.

ÜBERSETZUNG

       Die deutsche Übersetzung dieser Handbuchseite wurde von Martin Schulze <joey@infodrom.org>, Daniel Kobras
       <kobras@linux.de>,    Martin    Eberhard    Schauer    <Martin.E.Schauer@gmx.de>,    Helge     Kreutzmann
       <debian@helgefjell.de> und Mario Blättermann <mario.blaettermann@gmail.com> erstellt.

       Diese  Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer
       bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.

       Wenn Sie Fehler in der Übersetzung dieser  Handbuchseite  finden,  schicken  Sie  bitte  eine  E-Mail  an
       <debian-l10n-german@lists.debian.org>.