Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»

Mise à jour du livre

Le chapitre "Traitement des requêtes en parallèle" a été mis à jour.

Si vous voulez en savoir plus, veuillez "aimer" ou "me suivre" dans Book ;-)


Ce qui suit est un extrait du contenu du livre.


problème actuel

python lit le code source dans l'ordre à partir du haut, et lorsque le traitement d'une ligne est terminé, il exécute la ligne suivante dans l'ordre.

Par conséquent, avec le code source actuel,

--Accepter les connexions des clients (. Accept ())

Assurez-vous de suivre cet ordre.

En d'autres termes, ** "La prochaine demande ne sera pas acceptée tant que tout le traitement d'une demande ne sera pas terminé" ** Cela signifie que.

Cela devient un gros problème à mesure que le nombre de demandes augmente.


Par exemple, supposons que 10 demandes arrivent en même temps.

À ce moment, le serveur commencera à traiter la première demande qui vient en premier. Et si cette première demande est un processus très long, les 9 demandes suivantes devront attendre que le processus soit terminé.

Un cas courant consiste à lancer une requête avec des critères de recherche complexes sur un serveur de base de données et à attendre 30 secondes pour une réponse. Les performances globales seront bien meilleures si la machine traite les 9 autres requêtes pendant 30 secondes en attendant une réponse de la base de données.

De cette manière, pendant qu'un certain programme exécute un certain processus, l'exécution d'un autre programme en arrière-plan est appelée ** traitement parallèle ** ou ** traitement parallèle **.

Ce traitement parallèle est implémenté naturellement pour les serveurs Web généraux, donc implémentons-le également.

Colonnes: "Traitement parallèle" et "Traitement parallèle"

Permettez-moi d'expliquer la différence entre «traitement parallèle» et «traitement parallèle».

En général, traiter plusieurs monogoto en même temps est appelé "traitement parallèle".

Dans le monde informatique, le processeur est responsable de tout le traitement réel, mais un processeur ne peut toujours faire qu'un seul travail à la fois. Par conséquent, au sens strict, le "traitement parallèle" ne peut pas être réalisé avec une seule CPU.

Cependant, d'un point de vue humain, le traitement du processeur est si rapide que «Si vous faites ce travail et devenez" en attente ", passez à un autre travail, et si vous devenez" en attente "à nouveau, faites un autre travail." ` En changeant les processus à aborder l'un après l'autre, l'œil humain peut le voir comme s'il effectuait des tâches en même temps. (Selon le système d'exploitation, le processeur change de tâches l'une après l'autre en 0,2 seconde ou moins)

Dans l'ancien temps, il était naturel pour un ordinateur d'avoir un processeur, donc dans le monde informatique, il n'y avait pas de problème particulier à lire ce "traitement pseudo-parallèle" simplement comme "traitement parallèle". Cependant, vers 2000, avec la sortie / diffusion des processeurs dual-core, un ordinateur est venu à être équipé de deux ou quatre processeurs (plus précisément, des cœurs de processeur), et en faisant fonctionner ces processeurs en même temps, "pseudo" Il est devenu possible d'effectuer un "traitement parallèle réel" au lieu d'un "traitement parallèle".

Par conséquent, les programmeurs appellent «traitement pseudo-parallèle» «traitement ** parallèle **» afin de faire la distinction entre «traitement pseudo-parallèle» et «traitement vrai parallèle», qui étaient auparavant lus comme «traitement parallèle». Il est venu pour être.

Il est extrêmement difficile pour les humains de faire la distinction entre «traitement parallèle» et «traitement parallèle» en surface, et il n'est pratiquement pas nécessaire de faire la distinction entre les deux en termes de programmation tant que le réglage des performances de la machine n'est pas nécessaire. Par conséquent, dans ce document, ceux-ci sont collectivement appelés "traitement parallèle" sans aucune distinction particulière.

C'est une histoire très compliquée de savoir quand le traitement parallèle et le traitement parallèle sont utilisés correctement et comment ils affectent les performances. Je vais l'omettre dans ce livre. Il y a beaucoup d'informations disponibles sur Internet à ce sujet, donc si vous êtes intéressé, jetez-y un œil.

Code source

Voici le code source amélioré pour le traitement parallèle. Veuillez noter qu'il existe deux fichiers.

study/WebServer.py https://github.com/bigen1925/introduction-to-web-application-with-python/blob/main/codes/chapter13/WebServer2.py

study/WorkerThread.py https://github.com/bigen1925/introduction-to-web-application-with-python/blob/main/codes/chapter13/WebServer2.py

Commentaire

«Commun»

Les fichiers étant séparés, les caractères «Serveur:» et «Travailleur:» sont respectivement sortis dans le journal affichant l'enregistrement de traitement. Exemple)

print("=== Server:Démarrez le serveur===")
print("=== Worker:Mettre fin à la communication avec le client===")

WebServer.py

Lignes 28-31

                #Créer un thread pour gérer le client
                thread = WorkerThread(client_socket)
                #Exécuter le fil
                thread.start()

Créez un ** thread ** pour traiter le client qui a établi la connexion et démarrer le traitement du thread. Le traitement qui a été effectué par la méthode .handle_client () jusqu'à la dernière fois et le traitement des exceptions avant et après ont tous été déplacés vers le traitement dans ce thread.

Un ** thread ** est une séquence de traitement qui permet à un ordinateur de traiter en parallèle, ce qui sera expliqué en détail plus loin.

WorkerThread.py

9ème ligne-57ème ligne

class WorkerThread(Thread):
    #Répertoire avec fichiers exécutables
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    #Répertoire pour placer les fichiers à livrer de manière statique
    DOCUMENT_ROOT = os.path.join(BASE_DIR, "static")

    def __init__(self, client_socket: socket):
        super().__init__()

        self.client_socket = client_socket

    def run(self) -> None:
        """
Reçoit une socket connectée au client comme argument
Traitez la demande et envoyez la réponse
        """
        
        #Traitement correspondant au client...

Thread est une classe incluse dans le module threading, qui est une bibliothèque intégrée de python, et est une classe de base pour créer facilement des threads.

Lorsque vous utilisez Thread, créez une classe qui hérite de Thread et remplacez la méthode.run (). Une instance de cette classe crée un nouveau thread en appelant la méthode .start () et démarre le traitement de la méthode .run ().


La CPU ne peut pas traiter les programmes exécutés dans un thread en parallèle, mais les programmes exécutés dans plusieurs threads peuvent être traités en parallèle.

Auparavant, la classe WebServer traitait toutes les réponses client de manière séquentielle dans un seul thread.

Cependant, à partir de ce moment, bien que la classe WebServer puisse établir une connexion avec le client en utilisant un thread, la réponse au contenu de la requête est traitée en parallèle par un autre thread.

Cela évite la situation où une demande est trop longue pour en accepter une autre.

Colonne: Points à noter lors du traitement des threads

Fondamentalement, le traitement de différents threads s'exécute en tant que programmes séparés, donc même si une exception se produit dans un thread, elle ne sera pas propagée à un autre thread.

Par exemple, dans le passé, les demandes étaient traitées dans le même thread, donc si une exception se produisait pendant le traitement de la demande, le traitement principal (traitement de la réception de la demande) aurait pris fin à moins que l'exception ne soit traitée. À partir de ce moment, les demandes sont traitées dans des threads séparés, donc même si une exception se produit lors du traitement d'une demande dans un certain thread, s'il n'y a pas de gestion des exceptions, ce thread se terminera simplement et le thread principal sera affecté. il n'y a pas.

À première vue, cela peut paraître reconnaissant, mais cela ne devrait pas continuer en cas d'anomalie affectant l'ensemble du serveur.

Soyez sensible à la gestion des exceptions lors de l'utilisation de threads.


De plus, le fait de ramener de plus en plus les threads ne signifie pas que le traitement sera infiniment rapide.

Il y a une limite à la quantité que la CPU peut traiter en même temps. Dans une situation où la plupart des processus exécutés en parallèle utilisent une grande quantité de CPU, la quantité de traitement de la CPU peut atteindre la limite et l'exécution parallèle peut être retardée, et les performances peuvent ne pas être améliorées ou peuvent être diminuées. Le traitement qui fait que les performances du processeur deviennent un goulot d'étranglement et atteint la limite de vitesse de traitement est appelé «traitement lié au processeur».

Pour les services Web qui ont beaucoup de traitement lié au processeur, si vous augmentez inutilement le nombre de threads, la quantité de traitement du processeur peut atteindre sa limite et affecter la vitesse d'exécution d'autres programmes. De nombreux serveurs Web vous permettent de limiter le nombre de threads et de processus pour éviter cela.

Faites attention au nombre de branches de thread que votre programme aura dans le pire des cas.

Dans ce livre également, vous devez à l'origine définir une limite supérieure sur le nombre de threads qui peuvent être branchés, et python fournit une classe appelée ThreadPoolExecutor à cet effet. Si vous êtes intéressé, veuillez le vérifier.

Essayez de bouger

Déplaçons-le réellement.


Continuez avec Book!

Chapitre "Traitement des requêtes en parallèle"

Recommended Posts

Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»
Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»
Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»
Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»
Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»
Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»
Mise à jour de «Introduction à l'accueil de l'application Web Python pour les ingénieurs Web de 3e année qui sont lents»
[Introduction à l'application Udemy Python3 +] 43. instruction for else
Introduction à Python pour, pendant
[Introduction à l'application Udemy Python3 +] 42. pour instruction, instruction break et instruction continue
[Présentation de l'application Udemy Python3 +] 58. Lambda
[Présentation de l'application Udemy Python3 +] 31. Commentaire
[Présentation de l'application Udemy Python3 +] 57. Décorateur
[Présentation de l'application Udemy Python3 +] 56. Clôture
[Présentation de l'application Udemy Python3 +] 59. Générateur
[Introduction à l'application Udemy Python3 +] Résumé
Premiers pas avec Python pour les non-ingénieurs
Explication facile à comprendre de l'application Web Python (Django) même pour les débutants (5) [Introduction au fonctionnement de la base de données avec le shell Django]
[Introduction à Udemy Python3 + Application] 18. Méthode List
[Introduction à Udemy Python3 + Application] 63. Notation d'inclusion du générateur
[Introduction à Udemy Python3 + Application] 25. Méthode de type dictionnaire
[Introduction à l'application Udemy Python3 +] 33. instruction if
[Introduction à Udemy Python3 + Application] 13. Méthode de caractères
[Introduction à l'application Udemy Python3 +] 55. Fonctions intégrées
[Introduction à l'application Udemy Python3 +] 48. Définition des fonctions
[Introduction à l'application Udemy Python3 +] 10. Valeur numérique
[Introduction à l'application Udemy Python3 +] 41. fonction d'entrée
[Introduction à l'application Udemy Python3 +] 17. Opération de liste
[Introduction à l'application Udemy Python3 +] 65. Gestion des exceptions
[Introduction à l'application Udemy Python3 +] 11. Chaîne de caractères
[Introduction à l'application Udemy Python3 +] 44. fonction range
[Introduction à l'application Udemy Python3 +] 46. fonction zip
[Introduction à l'application Udemy Python3 +] 24. Type de dictionnaire
[Python] Conception d'applications Web pour l'apprentissage automatique
Une introduction à Python pour l'apprentissage automatique
[Introduction à Udemy Python3 + Application] 8. Déclaration de variable
[Introduction à Udemy Python3 + Application] 29. Méthode Set
[Introduction à l'application Udemy Python3 +] 16. Type de liste
[Introduction à Udemy Python3 + Application] 61. Notation d'inclusion de dictionnaire
[Introduction à l'application Udemy Python3 +] 22. Déballage de taples
Une introduction à Python pour les programmeurs en langage C
[Introduction à Udemy Python3 + Application] 47. Traitez le dictionnaire avec une instruction for
Prenons la version gratuite "Introduction à Python pour l'apprentissage automatique" en ligne jusqu'au 27/04
Une introduction aux applications Web Python auto-conçues pour un ingénieur Web de troisième année paresseux
Explication facile à comprendre de l'application Web Python (Django) même pour les débutants (4) [Route setting / Introduction to MTV design patterns]
Mis à jour vers Python 2.7.9
[Introduction à Udemy Python3 + Application] 26. Copie du dictionnaire
[Introduction à l'application Udemy Python3 +] 23. Comment utiliser Tapuru
[Introduction à Udemy Python3 + Application] 60. Notation d'inclusion de liste
[Introduction à Udemy Python3 + Application] 19. Copie de la liste
[Introduction à Udemy Python3 + Application] 38. Lors du jugement Aucun
[Introduction à l'application Udemy Python3 +] 40. Instruction while else
[Introduction à Udemy Python3 + Application] 62. Définir la notation d'inclusion
Étapes pour développer une application Web en Python
[Introduction à l'application Udemy Python3 +] 64. Espace de noms et portée
[Introduction à Python3 Jour 20] Chapitre 9 Démêler le Web (9.1-9.4)
[Introduction à Udemy Python3 + Application] 67. Arguments de ligne de commande
[Introduction à l'application Udemy Python3 +] 9. Tout d'abord, imprimez avec print
Introduction à la programmation (Python) TA Tendency pour les débutants
[Introduction à l'application Udemy Python3 +] 54. Qu'est-ce que Docstrings?
[Introduction à Udemy Python3 + Application] 37. Technique pour juger qu'il n'y a pas de valeur