Asynchrones I/O mit epoll und kqueue
Skalieren Sie auf viele Verbindungen mit epoll unter Linux und kqueue unter BSD oder macOS.
Asynchrones I/O mit epoll und kqueue ist eine kostenlose C++ Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C++ Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C++ Academy-Kurs umfasst insgesamt 4 Lektionen.
Warum asynchrones I/O?
Ein Thread pro Verbindung skaliert nicht auf Tausende oder Millionen von Clients. Asynchrones I/O ermöglicht es einem Thread, viele Sockets zu verwalten, indem er wartet, bis einer von ihnen lesbar oder beschreibbar wird.
Linux: epoll
Linux bietet eine skalierbare Ereignis-API. Fügen Sie Dateideskriptoren einer epoll-Instanz hinzu und warten Sie auf Ereignisse an beliebigen Deskriptoren.
#include <sys/epoll.h>
int epfd = epoll_create1(0);
epoll_event ev{};
ev.events = EPOLLIN;
ev.data.fd = sock;
epoll_ctl(epfd, EPOLL_CTL_ADD, sock, &ev);Auf Ereignisse warten
epoll_wait blockiert, bis Ereignisse verfügbar sind, und gibt anschließend die bereiten Deskriptoren zurück.
epoll_event events[64];
int n = epoll_wait(epfd, events, 64, -1);
for (int i = 0; i < n; ++i) {
int fd = events[i].data.fd;
handle_io(fd);
}Edge-Triggered vs. Level-Triggered
Es gibt zwei Modi:
- Level-triggered (Standard) – epoll meldet ein Ereignis weiterhin, solange eine Bedingung erfüllt ist
- Edge-triggered (
EPOLLET) – meldet nur eine Zustandsänderung; Sie müssen den Socket jedes Mal vollständig leeren
macOS und BSD: kqueue
kqueue ist das BSD-Gegenstück zu epoll und auch unter macOS verfügbar. Das Konzept ist ähnlich, die API jedoch anders.
#include <sys/event.h>
int kq = kqueue();
struct kevent ev;
EV_SET(&ev, sock, EVFILT_READ, EV_ADD, 0, 0, nullptr);
kevent(kq, &ev, 1, nullptr, 0, nullptr);Windows: IOCP
Windows verwendet I/O Completion Ports (IOCP) – ein auf dem Abschlussprinzip basierendes Modell (Benachrichtigung nach Abschluss) statt des Bereitschaftsmodells von epoll/kqueue.
Nicht blockierende Sockets
Setzen Sie Sockets mit fcntl(fd, F_SETFL, O_NONBLOCK) in den nicht blockierenden Modus. Andernfalls können Lese- und Schreibvorgänge die gesamte Ereignisschleife blockieren.
Das Muster der Ereignisschleife
Eine Schleife, die endlos läuft:
- Warten Sie auf bereite Ereignisse
- Führen Sie für jedes Ereignis I/O durch, bis die Operation blockieren würde
- Wiederholen Sie den Vorgang
Viele Clients verwalten
Ein einzelner epoll-Thread kann Zehntausende gleichzeitiger Verbindungen verwalten – das C10K-Problem. Moderne Systeme skalieren bis in den Millionenbereich.
Häufige Fallstricke
Achten Sie auf Folgendes:
- Den nicht blockierenden Modus nicht zu aktivieren
- Edge-triggered zu verwenden, ohne den Socket zu leeren
- Geschlossene FDs nicht aus dem epoll-Satz zu entfernen
- Pufferlecks pro Verbindung
Abstraktionen höherer Ebene
Eine epoll-Schleife von Hand zu schreiben ist fehleranfällig. Verwenden Sie für Produktionscode libuv, libevent oder Boost.Asio – diese Bibliotheken abstrahieren Plattformunterschiede und stellen getestete I/O-Schleifen bereit.
Asynchrones I/O vs. Threads
Asynchrones I/O ist besser skalierbar, aber schwieriger zu schreiben. Für Server mit einigen Tausend Verbindungen ist ein Thread-pro-Verbindung-Modell einfacher. Treffen Sie die Wahl anhand der erwarteten Auslastung.
Kurztest
Was ist der Unterschied zwischen den Modi Edge-triggered und Level-triggered in epoll?
Zusammenfassung
Asynchrones I/O skaliert auf massive Nebenläufigkeit, indem viele Sockets in einem Thread verarbeitet werden. Unter Linux wird epoll verwendet, unter BSD/macOS kqueue und unter Windows IOCP. Setzen Sie Sockets in den nicht blockierenden Modus. Verwenden Sie für Produktionscode eine Bibliothek (Asio, libuv, libevent), statt die Ereignisschleife selbst zu implementieren.
Häufig gestellte Fragen
Ist die Lektion „Asynchrones I/O mit epoll und kqueue“ kostenlos?
Ja — der vollständige Text von „Asynchrones I/O mit epoll und kqueue“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C++ Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C++ Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Asynchrones I/O mit epoll und kqueue“?
Skalieren Sie auf viele Verbindungen mit epoll unter Linux und kqueue unter BSD oder macOS. Du übst C++ Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um C++ Academy zu starten?
Keine Vorkenntnisse erforderlich. C++ Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Asynchrones I/O mit epoll und kqueue“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser C++ Academy-Lektion Code schreiben und ausführen?
Ja. Jede C++ Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- BSD-Sockets-API in C++
- Einen TCP-Echo-Server erstellen
- Asynchrones I/O mit epoll und kqueue
- Modernes asynchrones I/O mit Boost Asio