Maison Java javaDidacticiel Explication graphique et textuelle détaillée de la réutilisation des E/S en Java

Explication graphique et textuelle détaillée de la réutilisation des E/S en Java

May 28, 2017 am 09:23 AM

Cet article présente principalement les connaissances pertinentes sur la réutilisation de Java IO. Il est très bon et a une valeur de référence. Les amis qui en ont besoin peuvent s'y référer

Pour la capacité de traitement simultané du serveur. , ce dont nous avons besoin est : chaque milliseconde, le serveur peut traiter rapidement les messages sur des centaines de connexions TCP différentes reçues au cours de cette milliseconde. En même temps, il peut y avoir des centaines de milliers de messages sur le serveur qui n'ont pas été reçus au cours de la dernière milliseconde. quelques secondes. Une connexion relativement inactive pour envoyer et recevoir des messages. Le traitement de plusieurs connexions où des événements se produisent en parallèle en même temps est appelé concurrence ; le traitement de dizaines de milliers ou de centaines de milliers de connexions en même temps est une concurrence élevée. Ce que poursuit la programmation simultanée du serveur, c'est de traiter un nombre infini de connexions simultanées tout en maintenant une utilisation efficace des ressources telles que le processeur jusqu'à ce que les ressources physiques soient épuisées.

Il existe de nombreuses implémentations de modèles de programmation simultanée. Le plus simple est fourni avec des "threads", et un thread gère l'intégralité du cycle de vie d'une connexion. Avantages : Ce modèle est assez simple, il peut mettre en œuvre des scénarios commerciaux complexes et, en même temps, le nombre de threads peut être bien supérieur au nombre de processeurs. Cependant, le nombre de threads ne peut pas être augmenté à l’infini. Pourquoi ? Parce que le moment où un thread est exécuté est déterminé par l'algorithme de planification du noyau du système d'exploitation, l'algorithme de planification ne considère pas qu'un certain thread ne peut servir qu'une seule connexion. Il adoptera un gameplay unifié : l'exécutera lorsque la tranche de temps est écoulée, même si. ce fil Une fois exécuté, vous devrez continuer à dormir. Ce va-et-vient de threads de veille et de veille est bon marché lorsque le nombre de fois est petit, mais si le nombre total de threads dans le système d'exploitation est grand, il est coûteux (amplifié), car cette perte de planification technique affectera les threads. L'heure à laquelle le code métier est exécuté. Par exemple, la plupart des threads avec des connexions inactives à l'heure actuelle sont comme nos entreprises publiques. Leur efficacité d'exécution est trop faible. Lorsqu'ils se réveillent et se disputent les ressources CPU, ils se réveillent et dorment. Cela signifie que le nombre de threads d'entreprise privés traitant les connexions actives est réduit et la possibilité d'obtenir le CPU est réduite. Le CPU est le cœur de la compétitivité, et son inefficacité affecte le débit total du PIB. Notre objectif est de traiter des centaines de milliers de connexions simultanément. Lorsque des milliers de threads apparaissent, l'efficacité d'exécution du système ne peut plus répondre à une concurrence élevée.

Pour la programmation à haute concurrence, il n'existe actuellement qu'un seul modèle, qui est essentiellement la seule méthode efficace. Le traitement du message sur la connexion peut être divisé en deux étapes : l'attente que le message soit prêt et le traitement du message. Lors de l'utilisation du socket de blocage par défaut (par exemple, un thread regroupé pour traiter une connexion mentionnée ci-dessus), ces deux étapes sont souvent combinées en une seule, de sorte que le thread qui exploite le code du socket doit dormir pour attendre que le message soit prêt. , cela provoque la mise en veille et le réveil fréquents du thread en cas de concurrence élevée, affectant ainsi l'efficacité de l'utilisation du processeur.

La méthode de programmation à haute concurrence consiste bien entendu à séparer les deux étapes. Autrement dit, la section de code qui attend que le message soit prêt est séparée de la section de code qui traite le message. Bien entendu, cela nécessite également que le socket ne soit pas bloquant. Sinon, le segment de code qui traite le message peut facilement amener le thread à entrer en phase d'attente de veille lorsque les conditions ne sont pas remplies. La question est donc de savoir comment parvenir à cette étape d’attente que le message soit prêt ? Après tout, il attend toujours, ce qui signifie que le fil doit encore dormir ! La solution est d' interroger activement, ou de laisser 1 thread attendre toutes les connexions ! Il s'agit du multiplexage IO. Le multiplexage consiste à attendre que les messages soient prêts, mais il peut gérer plusieurs connexions en même temps ! Il peut également "attendre", ce qui peut également provoquer la mise en veille du thread, mais cela n'a pas d'importance car il est un à plusieurs et il peut surveiller toutes les connexions. De cette façon, lorsque notre thread est réveillé pour exécution, il doit y avoir des connexions prêtes à être exécutées par notre code, ce qui est efficace ! Il n'y a pas tellement de threads en compétition pour traiter la phase "attendre que le message soit prêt", et le monde entier est enfin clair !
Il existe de nombreuses implémentations du multiplexage. Sur linux, avant le noyau 2.4, les principales étaient select et poll. Maintenant, le courant dominant est epoll. Leurs méthodes d'utilisation semblent être très différentes, mais l'essence. c'est pareil.

L'efficacité est également différente, c'est pourquoi epoll a complètement remplacé select.

Parlons brièvement de la raison pour laquelle epoll remplace select.

Comme mentionné précédemment, la solution de base pour une concurrence élevée est d'avoir un seul thread "en attente que les messages soient prêts" pour toutes les connexions. Sur ce point, epoll et select ne sont pas controversés. Mais sélectionnez une chose qui ne va pas. Comme nous l'avons dit dans le premier chapitre de , lorsqu'il existe des centaines de milliers de connexions simultanées, il peut n'y avoir que des centaines de connexions actives chaque milliseconde, tandis que les centaines de milliers de connexions restantes. est inactif pendant cette milliseconde. La méthode d'utilisation de select est la suivante :
Connexions actives renvoyées ==select (toutes les connexions à surveiller)

Quand la méthode select sera-t-elle appelée ? Vous devez appeler ceci lorsque vous pensez avoir besoin de connaître les connexions actives par lesquelles les paquets sont arrivés. Par conséquent, l’appel de select sera appelé fréquemment lorsque la concurrence est élevée. Il faut donc voir si cette méthode fréquemment appelée est efficace, car sa légère perte d'efficacité sera amplifiée par le mot « fréquent ». Est-ce qu'il y a une perte d'efficacité ? Évidemment, il y a des centaines de milliers de connexions à surveiller, et seules des centaines de connexions actives sont renvoyées, ce qui est inefficace en soi. Après avoir été amplifié, vous constaterez que select est totalement incapable de gérer des dizaines de milliers de connexions simultanées.
Regardez quelques photos. Lorsque le nombre de connexions simultanées est inférieur à 1 000, le nombre d'exécutions sélectionnées n'est pas fréquent, et il ne semble pas y avoir beaucoup de différence avec epoll :

Cependant, une fois que le nombre de concurrence augmente, les défauts de select sont infiniment amplifiés par « l'exécution fréquente », et plus le nombre est simultané, plus c'est évident :

Parlons de la façon dont epoll résout le problème. Il utilise intelligemment 3 méthodes pour réaliser ce que fait la méthode select :

New epoll descriptor==epoll_create()

epoll_ctrl(epoll descriptor, add Ou Delete toutes les connexions à surveiller)

La connexion active renvoyée==epoll_wait (descripteur epoll)

Le principal avantage de cette procédure est de faire la distinction entre les appels fréquents et les opérations appelées rarement. Par exemple, epoll_ctrl est appelé moins fréquemment, tandis qu'epoll_wait est appelé très fréquemment. À l'heure actuelle, epoll_wait n'a presque aucun paramètre d'entrée, ce qui est beaucoup plus efficace que select. De plus, il n'augmentera pas le nombre de paramètres d'entrée à mesure que les connexions simultanées augmentent, ce qui entraînera une diminution de l'efficacité d'exécution du noyau.

Comment epoll est-il implémenté ? En fait, c'est très simple. Ces trois méthodes montrent qu'il est plus intelligent que de sélectionner pour éviter d'avoir à transmettre toutes les connexions à surveiller à chaque fois que epoll_wait appelle fréquemment "quelles connexions sont déjà dans la préparation du message". scène". de. Cela signifie qu'il maintient une structure de données en mode noyau pour sauvegarder toutes les connexions à surveiller. Cette structure de données est un arbre rouge-noir, et l'ajout et la réduction de ses nœuds se font via epoll_ctrl. C'est très simple :

L'arbre rouge-noir en bas à gauche de la photo est constitué de toutes les connexions à surveiller. La liste chaînée en haut à gauche affiche toutes les connexions actuellement actives. Par conséquent, lorsque epoll_wait est exécuté, il vérifie uniquement la liste liée en haut à gauche et renvoie la connexion dans la liste liée en haut à gauche à l'utilisateur. De cette façon, l'efficacité d'exécution d'epoll_wait peut-elle être faible ?

Enfin, jetons un coup d'œil aux deux méthodes de jeu ET et LT fournies par epoll, qui sont le déclencheur de bord traduit et le déclencheur horizontal. En fait, ces deux noms chinois sont plutôt appropriés. Ces deux méthodes d'utilisation visent toujours des problèmes d'efficacité, mais elles servent simplement à rendre plus précise la connexion renvoyée par epoll_wait.

Par exemple, nous devons surveiller si le tampon d'écriture d'une connexion est libre Lorsqu'il est "inscriptible", nous pouvons envoyer l'appel de réponse write au client depuis le mode utilisateur. Cependant, peut-être que lorsque la connexion est accessible en écriture, notre contenu de « réponse » est toujours sur le disque. Que se passe-t-il si la lecture du disque n'est pas terminée à ce moment-là ? Le fil de discussion ne doit pas être bloqué, la réponse ne sera donc pas envoyée. Cependant, la connexion peut vous être renvoyée la prochaine fois que vous epoll_wait, et vous devez vérifier si vous souhaitez la traiter. Probablement, notre programme a un autre module qui gère spécifiquement les E/S du disque, et il enverra une réponse lorsque les E/S du disque seront terminées. Ainsi, chaque fois que epoll_wait renvoie cette connexion « accessible en écriture » qui ne peut pas être traitée immédiatement, répond-elle aux attentes des utilisateurs ?

Ainsi, les modes ET et LT ont vu le jour. LT signifie que chaque connexion qui répond au statut attendu doit être renvoyée dans epoll_wait, donc elle traite tout le monde de la même manière et se situe sur une ligne horizontale. Ce n’est pas le cas d’ET qui préfère des liaisons retour plus précises. Dans l'exemple ci-dessus, une fois que la connexion devient accessible en écriture pour la première fois, si le programme n'écrit aucune donnée sur la connexion, alors epoll_wait ne renverra pas la connexion la prochaine fois. ET est appelé edge trigger, ce qui signifie que epoll_wait sera déclenché pour le renvoyer uniquement lorsque la connexion passe d'un état à un autre. On voit que la programmation d'ET est beaucoup plus compliquée. Au moins l'application doit faire attention à éviter que la connexion renvoyée par epoll_wait n'apparaisse : lorsqu'elle est inscriptible, la donnée n'est pas écrite mais elle attend le prochain "inscriptible" ; lorsqu'elle est lisible, les données ne sont pas lues mais elles attendent avec impatience la prochaine fois.

Bien sûr, il n'y aura pas de grande différence de performances dans les scénarios d'application généraux. L'avantage possible d'ET est que le nombre d'appels à epoll_wait sera réduit et, dans certains scénarios, la connexion ne sera pas réveillée lorsqu'elle sera activée. n'est pas nécessaire (ce réveil fait référence au retour de epoll_wait). Mais si c’est comme dans l’exemple que j’ai mentionné ci-dessus, parfois ce n’est pas seulement un problème de réseau, c’est lié au scénario d’application. Bien sûr, la plupart des frameworks open source sont écrits sur la base d'ET. Quant au framework, il poursuit des problématiques purement techniques, et vise bien sûr la perfection

.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Numéro de Smith en Java Numéro de Smith en Java Aug 30, 2024 pm 04:28 PM

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Questions d'entretien chez Java Spring Questions d'entretien chez Java Spring Aug 30, 2024 pm 04:29 PM

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Break or Return of Java 8 Stream Forach? Break or Return of Java 8 Stream Forach? Feb 07, 2025 pm 12:09 PM

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

Horodatage à ce jour en Java Horodatage à ce jour en Java Aug 30, 2024 pm 04:28 PM

Guide de TimeStamp to Date en Java. Ici, nous discutons également de l'introduction et de la façon de convertir l'horodatage en date en Java avec des exemples.

Programme Java pour trouver le volume de la capsule Programme Java pour trouver le volume de la capsule Feb 07, 2025 am 11:37 AM

Les capsules sont des figures géométriques tridimensionnelles, composées d'un cylindre et d'un hémisphère aux deux extrémités. Le volume de la capsule peut être calculé en ajoutant le volume du cylindre et le volume de l'hémisphère aux deux extrémités. Ce tutoriel discutera de la façon de calculer le volume d'une capsule donnée en Java en utilisant différentes méthodes. Formule de volume de capsule La formule du volume de la capsule est la suivante: Volume de capsule = volume cylindrique volume de deux hémisphères volume dans, R: Le rayon de l'hémisphère. H: La hauteur du cylindre (à l'exclusion de l'hémisphère). Exemple 1 entrer Rayon = 5 unités Hauteur = 10 unités Sortir Volume = 1570,8 unités cubes expliquer Calculer le volume à l'aide de la formule: Volume = π × r2 × h (4

PHP vs Python: comprendre les différences PHP vs Python: comprendre les différences Apr 11, 2025 am 12:15 AM

PHP et Python ont chacun leurs propres avantages, et le choix doit être basé sur les exigences du projet. 1.Php convient au développement Web, avec une syntaxe simple et une efficacité d'exécution élevée. 2. Python convient à la science des données et à l'apprentissage automatique, avec une syntaxe concise et des bibliothèques riches.

PHP: un langage clé pour le développement Web PHP: un langage clé pour le développement Web Apr 13, 2025 am 12:08 AM

PHP est un langage de script largement utilisé du côté du serveur, particulièrement adapté au développement Web. 1.Php peut intégrer HTML, traiter les demandes et réponses HTTP et prend en charge une variété de bases de données. 2.PHP est utilisé pour générer du contenu Web dynamique, des données de formulaire de traitement, des bases de données d'accès, etc., avec un support communautaire solide et des ressources open source. 3. PHP est une langue interprétée, et le processus d'exécution comprend l'analyse lexicale, l'analyse grammaticale, la compilation et l'exécution. 4.PHP peut être combiné avec MySQL pour les applications avancées telles que les systèmes d'enregistrement des utilisateurs. 5. Lors du débogage de PHP, vous pouvez utiliser des fonctions telles que error_reportting () et var_dump (). 6. Optimiser le code PHP pour utiliser les mécanismes de mise en cache, optimiser les requêtes de base de données et utiliser des fonctions intégrées. 7

Créer l'avenir : programmation Java pour les débutants absolus Créer l'avenir : programmation Java pour les débutants absolus Oct 13, 2024 pm 01:32 PM

Java est un langage de programmation populaire qui peut être appris aussi bien par les développeurs débutants que par les développeurs expérimentés. Ce didacticiel commence par les concepts de base et progresse vers des sujets avancés. Après avoir installé le kit de développement Java, vous pouvez vous entraîner à la programmation en créant un simple programme « Hello, World ! ». Une fois que vous avez compris le code, utilisez l'invite de commande pour compiler et exécuter le programme, et « Hello, World ! » s'affichera sur la console. L'apprentissage de Java commence votre parcours de programmation et, à mesure que votre maîtrise s'approfondit, vous pouvez créer des applications plus complexes.

See all articles