Di recente ho visto testato uno scenario in cui più thread hanno eseguito il polling su un socket di dominio unix in ascolto e quindi hanno accettato la connessione. Tutti i thread sono stati attivati utilizzando la chiamata di sistema poll().
Questa era una build personalizzata del kernel Linux piuttosto che una build distro, quindi forse c'è un'opzione di configurazione del kernel che la modifica, ma non so quale sarebbe.
Non abbiamo provato epoll.
Per anni, la maggior parte dei kernel unix/linux serializza la risposta a accept(2), in altre parole, solo un thread viene riattivato se più di uno sta bloccando accept(2) rispetto a un singolo descrittore di file aperto.
OTOH, molti (se non tutti) i kernel hanno ancora il problema del branco tonante nel modello select-accept come descrivi.
Ho scritto un semplice script ( https://gist.github.com/kazuho/10436253 ) per verificare l'esistenza del problema e ho scoperto che il problema esiste su Linux 2.6.32 e Darwin 12.5.0 (OS X 10.8 .5).
Questo è un problema molto vecchio, e per la maggior parte non esiste più. Il kernel Linux (negli ultimi anni) ha subito una serie di cambiamenti nel modo in cui gestisce e instrada i pacchetti nello stack di rete e include molte ottimizzazioni per garantire sia bassa latenza che equità (ovvero, ridurre al minimo l'inedia).
Detto questo, select system ha una serie di problemi di scalabilità semplicemente tramite la sua API. Quando si dispone di un numero elevato di descrittori di file, il costo di una chiamata select è molto elevato. Ciò è dovuto principalmente alla necessità di creare, controllare e mantenere i set FD che vengono passati da e verso la chiamata di sistema.
Al giorno d'oggi, il modo migliore per eseguire l'IO asincrono è con epoll . L'API è molto più semplice e si adatta molto bene a vari tipi di carico (molte connessioni, molto throughput, ecc.)