0Pricing
C Academy · Lezione

Gestire più client

select e poll

Gestire più client è una lezione C Academy gratuita su CoddyKit. Questa è la lezione 4 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.

Il problema della concorrenza

Un server semplice gestisce un client alla volta. Se un client è lento, tutti gli altri devono aspettare. Per servire molti client contemporaneamente, è necessario un modello diverso.

Approcci alla concorrenza

Tre strategie comuni:

  • Un thread o processo per client: semplice, ma oneroso su larga scala
  • Multiplexing dell'I/O con select o poll: un thread controlla molti socket
  • Event loop con epoll/kqueue: scalabile fino a migliaia di connessioni

Cosa fa select

select() controlla un insieme di descrittori di file e indica quali sono pronti per la lettura o la scrittura, oppure presentano errori, tutto tramite un'unica chiamata bloccante. In questo modo un thread può servire molti socket.

Nozioni di base su fd_set

select utilizza una maschera di bit fd_set. La gestisca con le macro: FD_ZERO, FD_SET, FD_CLR e FD_ISSET.

#include <sys/select.h>

void setup_set(fd_set *set, int listen_fd) {
    FD_ZERO(set);          /* clear all */
    FD_SET(listen_fd, set); /* watch the listener */
}

Chiamare select

select richiede il descrittore più alto più uno e modifica l'insieme direttamente, contrassegnando i descrittori pronti. Poiché è distruttivo, ricrei l'insieme prima di ogni chiamata.

#include <sys/select.h>
#include <stdio.h>

int wait_ready(int maxfd, fd_set *read_set) {
    int n = select(maxfd + 1, read_set, NULL, NULL, NULL);
    if (n < 0) perror("select");
    return n; /* number of ready fds */
}

Il ciclo del server con select

Lo schema è il seguente: ricrei l'insieme, chiami select, quindi, per ogni descrittore pronto, accetti un nuovo client se si tratta del socket in ascolto oppure legga i dati se si tratta di un client.

#include <sys/select.h>

void loop_skeleton(int listen_fd, fd_set *master, int maxfd) {
    fd_set work;
    for (;;) {
        work = *master;           /* copy, select destroys it */
        select(maxfd + 1, &work, NULL, NULL, NULL);
        for (int fd = 0; fd <= maxfd; fd++) {
            if (!FD_ISSET(fd, &work)) continue;
            /* fd == listen_fd -> accept; else -> recv */
        }
    }
}

Tenere traccia dei client

Quando accetta una nuova connessione, aggiunga il relativo fd all'insieme principale e aggiorni maxfd. Quando un client si disconnette (recv restituisce 0), esegua close e rimuova il descrittore dall'insieme con FD_CLR.

#include <sys/select.h>
#include <unistd.h>

void add_client(fd_set *master, int *maxfd, int conn) {
    FD_SET(conn, master);
    if (conn > *maxfd) *maxfd = conn;
}
void drop_client(fd_set *master, int conn) {
    close(conn);
    FD_CLR(conn, master);
}

Limiti di select

select presenta alcuni svantaggi:

  • Limitato a FD_SETUP descrittori (spesso 1024)
  • Scansione O(n) di tutti gli fd a ogni chiamata
  • L'insieme deve essere ricreato a ogni iterazione

Per molte connessioni, poll o epoll offrono una scalabilità migliore.

Cosa offre poll

poll() utilizza un array di struct pollfd anziché una maschera di bit fissa, quindi non ha il limite di 1024 descrittori e non distrugge l'input a ogni chiamata.

#include <poll.h>

void setup_poll(struct pollfd *pfd, int listen_fd) {
    pfd[0].fd = listen_fd;
    pfd[0].events = POLLIN; /* notify when readable */
}

Chiamare poll

poll rimane bloccato finché almeno un fd non è pronto (oppure scade il timeout), quindi imposta revents per ogni voce pronta.

#include <poll.h>
#include <stdio.h>

int poll_ready(struct pollfd *pfds, int count) {
    int n = poll(pfds, count, -1); /* -1 = block forever */
    if (n < 0) perror("poll");
    return n;
}

Scalare: epoll

Per migliaia di connessioni, epoll di Linux (e kqueue dei sistemi BSD) restituisce solo i descrittori pronti in O(1) per evento, evitando la scansione completa eseguita da select e poll.

Verifica rapida

Verifichi la Sua comprensione della gestione di più client.

Riepilogo

Ha imparato a servire molti client con un solo thread.

  • select controlla molti fd; li gestisca con le macro FD_
  • Ricrei l'insieme a ogni ciclo perché select è distruttivo
  • Aggiunga i client accettati all'insieme; li rimuova alla disconnessione
  • poll evita il limite di 1024; epoll è scalabile fino a migliaia di connessioni

Domande Frequenti

La lezione «Gestire più client» è gratuita?

Sì — il testo completo di «Gestire più client» è 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 «Gestire più client»?

select e poll 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 4 di 4.

Quanto tempo richiede la lezione «Gestire più client»?

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. Panoramica dei socket
  2. Server TCP
  3. Client TCP
  4. Gestire più client
← Torna a C Academy