Autrefois, dans les systèmes Unix, le traitement des E / S pouvait être rendu asynchrone avec select (), et le traitement ne pouvait être effectué que lorsque l'état du descripteur de fichier changeait. C'était (apparemment) une technique efficace à une époque où les ressources mémoire et serveur étaient extrêmement faibles. Dans la seconde moitié des années 90 et la première moitié des années 2000, le multi-threading est devenu courant, et du côté serveur, les connexions ont été multiplexées en passant la socket du client qui a été acceptée et acceptée au thread et en envoyant et en recevant. (Bien sûr, asynchrone était également actif en fonction de l'objectif)
Depuis la seconde moitié des années 2000, le problème C10K fait du bruit, et node.js et nginx sont apparus. Le traitement asynchrone qui surveille l'état des descripteurs en rendant à nouveau les sockets non bloquants attirera plus d'attention que la méthode de création d'un grand nombre de threads et de consommation de ressources et de mémoire. Et récemment, des bibliothèques telles que javascript promise, RX, Reactive Extension qui peuvent décrire efficacement le traitement asynchrone dans un endroit proche de l'interface utilisateur côté client sont apparues.
Cependant, lorsque l'on considère le traitement asynchrone côté serveur, il n'est pas possible d'utiliser pleinement le multi-cœur et le multi-CPU simplement en traitant les E / S asynchrones avec un seul thread. Par conséquent, il existe également une méthode d'attente asynchrone de l'état prêt du socket après l'avoir reçu avec Accept (), et lorsque le socket devient prêt, le thread envoie et reçoit réellement. Le traitement asynchrone lui-même a plusieurs méthodes telles que select (), poll et epoll. De plus, il existe deux méthodes pour multiplexer les processus: l'utilisation de threads et les processus de fourche. Il existe également une méthode pour créer des threads et des processus à l'avance et leur transmettre des données.
Méthode | mérite | デmérite |
---|---|---|
select | Réduction de la consommation de mémoire et de ressources | Il y a une limite aux descripteurs qui peuvent être manipulés Impossible de gérer d'autres sockets pendant le traitement de transmission / réception d'un socket |
poll | Réduction de la consommation de mémoire et de ressources Aucune limite de descripteur |
Impossible de gérer d'autres sockets pendant le traitement de transmission / réception d'un socket |
EPOLL | Version plus rapide du sondage Aucune limite de descripteur |
Impossible de gérer d'autres sockets pendant le traitement de transmission / réception d'un socket |
fork | Pas beaucoup de prises en attente | Coût de génération de processus élevé |
thread | Pas beaucoup de prises en attente | Consommer le coût de création de thread et la zone de pile de connexion |
pre-fork | Pas beaucoup de prises en attente Le coût de création du processus est uniquement au démarrage |
Efforts pour transférer et verrouiller les données et gérer les processus |
pre-thread | Pas beaucoup de prises en attente Le coût de création de thread est uniquement au démarrage |
Efforts de transfert de données, de traitement de verrouillage et de gestion des threads |
EPOLL+thread | Latence maximale tout en réduisant la consommation de mémoire et de ressources | Coût de création de thread. Efforts de transfert de données et de gestion des threads |
EPOLL+pre thread | Latence maximale tout en réduisant la consommation de mémoire et de ressources | Le tracas du passage des données et de la gestion des threads est plus compliqué, mais s'il est bien implémenté, il devrait donner des performances parfaites. |
Cette zone est "[Linux Network Programming Bible](http://www.amazon.co.jp/Linux Network Programming Bible-Mitsuyuki Omata-ebook / dp / B00O8GIL62 / ref = sr_1_1? Ie = UTF8 & qid = 1429454642 & sr = 8- 1) »est détaillé.
Personnellement, je pense que "EPOLL + thread" est bon, mais selon les benchmarks du livre ci-dessus, "EPOLL + thread" a le temps de connexion le plus rapide, mais "fork" a la transmission et la réception les plus rapides. Il semble. En termes de commande globale, y compris le temps de connexion, le "pré-thread" était le plus rapide. En ce qui concerne l'envoi et la réception, le résultat est qu'il est plus rapide d'utiliser normalement "poll" et "EPOLL" que de faire des choses spéciales telles que des fourches et des threads comprenant "pré- ~" (est-ce vrai? ??). Au fait, il est écrit que "EPOLL + thread" est 4ème au total et plus lent que "select", "poll" et "EPOLL", mais ce résultat est également incroyable.
Le contenu du benchmark semble être une expérience dans laquelle 1000 threads sont démarrés en répétant le processus de connexion en envoyant et en recevant 50 fois, et le serveur est un noyau de numérotation, et seule la partie send () est threadée ou fourchue.
Même si les threads et les fourches sont pré-générés, les performances se détérioreront-elles en raison de la transmission et du partage de données de verrouillage? Je pense qu'il est tout à fait possible que le point de base du cadran ait un effet (le livre dit également qu'il s'agit d'une simple comparaison sans surveillance des ressources côté serveur).
Puisque "EPOLL + pre-thread" n'est pas introduit, cela peut être le plus rapide si le nombre de threads est correctement supprimé dans un environnement multicœur. En écrivant par moi-même, je pense réduire le nombre de threads avec "EPOLL + pre-thread".
À propos, le livre a également introduit une méthode de traitement de plusieurs S'accepte avec des threads, mais je ne connais pas les avantages et les inconvénients de cette méthode car elle se bloque et l'un d'eux devient le récepteur.