0Pricing
C Academy · Lezione

Configurare epoll

Crei e registri un insieme epoll.

Configurare epoll è una lezione C Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C Academy include 4 lezioni in totale.

Creazione di un'istanza epoll

Tutto inizia con un'istanza epoll, che è a sua volta un descrittore di file. La si crea con epoll_create1().

L'argomento è un campo di flag: passi 0 per il comportamento predefinito oppure EPOLL_CLOEXEC per chiudere automaticamente il descrittore durante exec(). Il fd restituito è quello da passare a tutte le altre chiamate epoll.

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

epoll_create1 rispetto a epoll_create

La versione precedente epoll_create(int size) accettava un suggerimento sulla dimensione, ma ora il kernel lo ignora; l'unico requisito era che fosse positivo.

Preferisca epoll_create1(): accetta dei flag invece di una dimensione priva di significato e consente di richiedere EPOLL_CLOEXEC in modo atomico, evitando una chiamata separata a fcntl().

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

La struct epoll_event

Sia gli eventi di interesse sia i risultati vengono espressi tramite struct epoll_event. Contiene una maschera di bit events e una union data.

La union data contiene ciò che desidera ricevere quando l'evento si verifica: comunemente data.fd, ma può anche essere un data.ptr che punta a un oggetto connessione allocato da Lei.

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

Registrazione con EPOLL_CTL_ADD

epoll_ctl() gestisce l'elenco degli eventi di interesse. Utilizzi l'operazione EPOLL_CTL_ADD per iniziare a monitorare un descrittore.

Passi il fd di epoll, l'operazione, il fd di destinazione e un puntatore alla Sua epoll_event. Da questo momento epoll segnalerà quando quel descrittore è pronto.

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

Flag degli eventi: EPOLLIN ed EPOLLOUT

La maschera events indica ciò che interessa monitorare. EPOLLIN significa che il descrittore è leggibile; EPOLLOUT significa che è scrivibile.

In genere si monitora EPOLLIN su un socket in ascolto (per accettare connessioni) e sui socket dei client (per leggere). Aggiunga EPOLLOUT solo quando dispone di dati nel buffer che non sono stati inviati completamente.

ev.events = EPOLLIN | EPOLLOUT;

Flag di errore e chiusura

Il kernel segnala sempre determinate condizioni, anche se non le ha richieste: EPOLLERR per gli errori, EPOLLHUP per una chiusura e EPOLLRDHUP quando l'altro estremo chiude una sola direzione della connessione.

Verifichi questi flag nel gestore; ignorare EPOLLHUP su un socket non più attivo porta a un ciclo continuo nel ciclo degli eventi.

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

Modifica degli eventi di interesse con EPOLL_CTL_MOD

Una volta registrato un descrittore, può modificarne la maschera degli eventi senza rimuoverlo. Utilizzi EPOLL_CTL_MOD.

Un modello comune è il seguente: una connessione monitora normalmente solo EPOLLIN, poi passa a EPOLLIN | EPOLLOUT quando il buffer di invio si riempie, e torna alla configurazione precedente dopo averlo svuotato.

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

Rimozione con EPOLL_CTL_DEL

Quando una connessione si chiude, smetta di monitorarla con EPOLL_CTL_DEL. L'ultimo argomento epoll_event viene ignorato e, nei kernel moderni, può essere NULL.

Noti che la chiusura di un descrittore lo rimuove automaticamente da tutti gli elenchi di interesse epoll, ma eliminarlo esplicitamente prima della chiusura mantiene chiara la gestione interna.

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

Level-triggered ed edge-triggered

Per impostazione predefinita epoll è level-triggered: finché un descrittore rimane leggibile, ogni epoll_wait() lo segnala. È un comportamento tollerante e semplice da usare.

Aggiunga il flag EPOLLET per la modalità edge-triggered: riceve una notifica solo quando cambia lo stato di disponibilità, quindi deve svuotare completamente il socket in un ciclo fino a EAGAIN.

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

Memorizzazione di un puntatore al contesto

Invece di data.fd, può memorizzare in data.ptr un puntatore a una struct specifica per la connessione. Quando l'evento si verifica, riceve direttamente quel puntatore, senza bisogno di una tabella di ricerca.

Ricordi però che si tratta di una union: se imposta data.ptr, non può anche leggere data.fd dallo stesso evento.

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

Pulizia

L'istanza epoll è semplicemente un descrittore di file, quindi la rilasci con close() quando il server si arresta.

La chiusura del fd di epoll libera l'elenco degli eventi di interesse del kernel. Gli eventuali socket monitorati ancora aperti restano aperti; li chiuda separatamente per rilasciare le relative risorse.

close(epfd);

Verifica rapida

Verifichi la Sua comprensione dell'API per la configurazione di epoll.

Riepilogo

Crei un'istanza con epoll_create1(), quindi gestisca gli eventi di interesse tramite epoll_ctl() usando ADD, MOD e DEL. Ogni struct epoll_event contiene una maschera events e una union data.

Scelga il comportamento level-triggered per semplicità oppure EPOLLET per le prestazioni edge-triggered. Nel prossimo passaggio useremo questi componenti in un ciclo degli eventi.

Domande Frequenti

La lezione «Configurare epoll» è gratuita?

Sì — il testo completo di «Configurare epoll» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C Academy, passa a CoddyKit PRO. Il corso C Academy include 4 lezioni in totale.

Cosa imparerò in «Configurare epoll»?

Crei e registri un insieme epoll. Eserciti C Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C Academy?

Non è richiesta alcuna esperienza precedente. C Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Configurare epoll»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C Academy?

Sì. Ogni lezione C Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. I/O bloccante e non bloccante
  2. Configurare epoll
  3. Il ciclo di eventi
  4. Un semplice server echo
← Torna a C Academy