0Pricing
C Academy · Lektion

epoll einrichten

Erstellen und registrieren Sie eine epoll-Menge.

epoll einrichten ist eine kostenlose C Academy-Lektion auf CoddyKit. Dies ist Lektion 2 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.

Erstellen einer epoll-Instanz

Alles beginnt mit einer epoll-Instanz, die selbst ein Dateideskriptor ist. Erstellen Sie sie mit epoll_create1().

Das Argument ist ein Flag-Feld: Übergeben Sie 0 für das Standardverhalten oder EPOLL_CLOEXEC, damit der Deskriptor über exec() hinweg automatisch geschlossen wird. Der zurückgegebene fd wird an alle weiteren epoll-Aufrufe übergeben.

int epfd = epoll_create1(EPOLL_CLOEXEC);
if (epfd == -1) { perror("epoll_create1"); exit(1); }

epoll_create1 im Vergleich zu epoll_create

Das ältere epoll_create(int size) erwartete einen Größenhinweis, den der Kernel inzwischen ignoriert; die einzige Voraussetzung war, dass er positiv ist.

Bevorzugen Sie epoll_create1(): Die Funktion erwartet statt einer bedeutungslosen Größe Flags und ermöglicht es Ihnen, EPOLL_CLOEXEC atomar anzufordern, sodass kein separater fcntl()-Aufruf erforderlich ist.

/* legacy form, size arg ignored by kernel */
int epfd = epoll_create(1);

Die Struktur epoll_event

Sowohl Überwachungsinteressen als auch Ergebnisse werden über struct epoll_event ausgedrückt. Sie enthält eine events-Bitmaske und eine data-Union.

Die data-Union enthält beliebige Daten, die beim Eintreten des Ereignisses zurückgegeben werden sollen: häufig data.fd, aber auch ein data.ptr, das auf ein von Ihnen angelegtes Verbindungsobjekt zeigen kann.

struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = listen_fd;

Registrieren mit EPOLL_CTL_ADD

epoll_ctl() verwaltet die Überwachungsliste. Verwenden Sie die Operation EPOLL_CTL_ADD, um mit der Überwachung eines Deskriptors zu beginnen.

Sie übergeben den epoll-fd, die Operation, den Ziel-fd und einen Zeiger auf Ihr epoll_event. Danach meldet epoll, sobald dieser Deskriptor bereit ist.

struct epoll_event ev = { .events = EPOLLIN, .data.fd = listen_fd };
if (epoll_ctl(epfd, EPOLL_CTL_ADD, listen_fd, &ev) == -1)
    perror("epoll_ctl: add");

Ereignis-Flags: EPOLLIN und EPOLLOUT

Die events-Maske gibt an, was Sie interessiert. EPOLLIN bedeutet, dass der Deskriptor lesbar ist; EPOLLOUT bedeutet, dass er beschreibbar ist.

Normalerweise überwachen Sie EPOLLIN am Listening-Socket (zum Annehmen von Verbindungen) und an Client-Sockets (zum Lesen). Fügen Sie EPOLLOUT nur hinzu, wenn gepufferte Daten zuvor nicht vollständig gesendet werden konnten.

ev.events = EPOLLIN | EPOLLOUT;

Fehler- und Hangup-Flags

Der Kernel meldet bestimmte Zustände immer, auch wenn Sie sie nicht angefordert haben: EPOLLERR für Fehler, EPOLLHUP für einen Hangup und EPOLLRDHUP für das halbe Schließen durch die Gegenstelle.

Prüfen Sie diese Flags in Ihrem Handler; wenn Sie EPOLLHUP bei einem getrennten Socket ignorieren, führt das zu einer Endlosschleife in der Ereignisschleife.

if (ev.events & (EPOLLERR | EPOLLHUP)) {
    close(ev.data.fd);
    continue;
}

Überwachungsinteressen mit EPOLL_CTL_MOD ändern

Sobald ein Deskriptor registriert ist, können Sie seine Ereignismaske ändern, ohne ihn zu entfernen. Verwenden Sie dazu EPOLL_CTL_MOD.

Ein häufiges Muster: Eine Verbindung überwacht normalerweise nur EPOLLIN, wechselt aber zu EPOLLIN | EPOLLOUT, wenn sich ihr Sendepuffer füllt, und danach wieder zurück, sobald er geleert ist.

ev.events = EPOLLIN | EPOLLOUT;
ev.data.fd = conn_fd;
epoll_ctl(epfd, EPOLL_CTL_MOD, conn_fd, &ev);

Entfernen mit EPOLL_CTL_DEL

Wenn eine Verbindung geschlossen wird, beenden Sie ihre Überwachung mit EPOLL_CTL_DEL. Das abschließende epoll_event-Argument wird ignoriert und darf bei modernen Kerneln NULL sein.

Beachten Sie, dass das Schließen eines Deskriptors ihn automatisch aus allen epoll-Überwachungslisten entfernt. Durch explizites Löschen vor dem Schließen bleibt Ihre Verwaltung jedoch übersichtlich.

epoll_ctl(epfd, EPOLL_CTL_DEL, conn_fd, NULL);
close(conn_fd);

Level-Triggered im Vergleich zu Edge-Triggered

Standardmäßig arbeitet epoll level-triggered: Solange ein Deskriptor lesbar bleibt, meldet ihn jeder Aufruf von epoll_wait(). Das ist tolerant und einfach.

Fügen Sie das Flag EPOLLET für den edge-triggered-Modus hinzu: Sie werden nur benachrichtigt, wenn sich die Bereitschaft ändert. Daher müssen Sie den Socket in einer Schleife vollständig leeren, bis EAGAIN zurückgegeben wird.

ev.events = EPOLLIN | EPOLLET;  /* edge-triggered */
epoll_ctl(epfd, EPOLL_CTL_ADD, conn_fd, &ev);

Einen Kontextzeiger speichern

Statt data.fd können Sie data.ptr speichern, das auf eine Verbindungsstruktur pro Verbindung zeigt. Wenn das Ereignis eintritt, erhalten Sie diesen Zeiger direkt zurück; eine Nachschlagetabelle ist nicht erforderlich.

Denken Sie aber an die Union: Wenn Sie data.ptr setzen, können Sie aus demselben Ereignis nicht zusätzlich data.fd auslesen.

struct conn *c = malloc(sizeof *c);
c->fd = conn_fd;
ev.events = EPOLLIN;
ev.data.ptr = c;
epoll_ctl(epfd, EPOLL_CTL_ADD, conn_fd, &ev);

Aufräumen

Die epoll-Instanz ist lediglich ein Dateideskriptor. Geben Sie sie daher beim Herunterfahren des Servers mit close() frei.

Beim Schließen des epoll-fd wird die Überwachungsliste des Kernels freigegeben. Noch geöffnete überwachte Sockets bleiben geöffnet; schließen Sie diese separat, um ihre Ressourcen freizugeben.

close(epfd);

Kurze Überprüfung

Überprüfen Sie Ihr Verständnis der epoll-Einrichtungs-API.

Zusammenfassung

Sie erstellen eine Instanz mit epoll_create1() und verwalten anschließend die Überwachung mit epoll_ctl() über ADD, MOD und DEL. Jedes struct epoll_event enthält eine events-Maske und eine data-Union.

Wählen Sie für Einfachheit Level-Triggered oder für eine bessere Edge-Triggered-Leistung EPOLLET. Als Nächstes steuern wir diese Bestandteile über eine Ereignisschleife.

Häufig gestellte Fragen

Ist die Lektion „epoll einrichten“ kostenlos?

Ja — der vollständige Text von „epoll einrichten“ 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 „epoll einrichten“?

Erstellen und registrieren Sie eine epoll-Menge. 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 2 von 4.

Wie lange dauert die Lektion „epoll einrichten“?

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

  1. Blockierendes und nicht blockierendes I/O
  2. epoll einrichten
  3. Die Event Loop
  4. Ein einfacher Echo-Server
← Zurück zu C Academy