Ich habe kürzlich ein Szenario getestet, in dem mehrere Threads einen lauschenden Unix-Domain-Socket abgefragt und dann die Verbindung akzeptiert haben. Alle Threads wurden mit dem poll()-Systemaufruf aufgeweckt.
Dies war eher ein benutzerdefinierter Build des Linux-Kernels als ein Distributions-Build, also gibt es vielleicht eine Kernel-Konfigurationsoption, die ihn ändert, aber ich weiß nicht, was das wäre.
Wir haben epoll nicht ausprobiert.
Seit Jahren serialisieren die meisten Unix/Linux-Kernel Antworten auf Accept(2)s, mit anderen Worten, nur ein Thread wird aufgeweckt, wenn mehr als einer auf Accept(2) gegen einen einzigen offenen Dateideskriptor blockiert.
OTOH, viele (wenn nicht alle) Kernel haben immer noch das donnernde Herdenproblem im Select-Accept-Muster, wie Sie es beschreiben.
Ich habe ein einfaches Skript ( https://gist.github.com/kazuho/10436253 ) geschrieben, um das Vorhandensein des Problems zu überprüfen, und herausgefunden, dass das Problem unter Linux 2.6.32 und Darwin 12.5.0 (OS X 10.8 .5).
Dies ist ein sehr altes Problem und existiert größtenteils nicht mehr. Der Linux-Kernel hat (in den letzten Jahren) eine Reihe von Änderungen erfahren, wie er Pakete im Netzwerk-Stack verarbeitet und weiterleitet, und enthält viele Optimierungen, um sowohl niedrige Latenz als auch Fairness (d. h. Minimierung von Hunger) sicherzustellen. P>
Das heißt, die Auswahl System hat eine Reihe von Skalierbarkeitsproblemen einfach über seine API. Wenn Sie eine große Anzahl von Dateideskriptoren haben, sind die Kosten für einen Auswahlaufruf sehr hoch. Dies liegt hauptsächlich daran, dass die FD-Sätze, die an und von dem Systemaufruf übergeben werden, erstellt, überprüft und gewartet werden müssen.
Heutzutage ist epoll der bevorzugte Weg für asynchrones IO . Die API ist viel einfacher und skaliert sehr gut über verschiedene Arten von Last (viele Verbindungen, viel Durchsatz usw.)