Maison > développement back-end > Tutoriel Python > Concurrence et parallélisme en Python

Concurrence et parallélisme en Python

Patricia Arquette
Libérer: 2025-01-05 03:59:39
original
901 Les gens l'ont consulté

Oui, j'avais arrêté de publier ici, mais d'un point de vue marketing il vaut mieux continuer à publier... On continue.

Texte initialement publié ici.


L'objectif de ce texte est de donner un résumé direct des concepts de base nécessaires pour comprendre la concurrence et le parallélisme dans le langage Python. Je recommande d'avoir un minimum de connaissances sur le sujet ou de combiner ce texte avec des études provenant d'autres sources. Toutes les références sont en fin de texte.

Je couvrirai les sujets suivants :

  • Qu'est-ce qu'un processus ?
  • Que sont les fils de discussion ?
  • Que signifient les limites d'E/S et les limites de CPU ?
  • Qu'est-ce que Python GIL ?
  • Qu'est-ce que la concurrence ?
  • Qu'est-ce que le parallélisme ?
  • La bibliothèque asyncio
  • La bibliothèque de threads
  • La bibliothèque multitraitement

Qu'est-ce qu'un processus ?

En informatique, un processus est une instance d'une application en cours d'exécution. Si vous ouvrez une application sur votre ordinateur, telle qu'un navigateur, cette application sera associée à un processus. Un processus est composé de :

  • Contexte matériel : stocke le contenu des registres généraux et spécifiques au CPU
  • Contexte logiciel : précise les ressources pouvant être allouées par le processus
  • Espace d'adressage : précise la zone de mémoire à laquelle appartient le processus

L'image suivante est tirée du livre de Francis Machado et Luis Maia :

Concorrência e paralelismo em Python

Ces informations sont nécessaires pour exécuter un programme.

Que sont les fils ?

Un thread est un sous-programme d'un programme, étant la plus petite unité d'exécution gérée par un système d'exploitation et un composant d'un processus.

Les différents threads d'un processus hypothétique peuvent être exécutés simultanément (ce que nous comprendrons bientôt), partageant des ressources telles que la mémoire. Différents processus ne partagent pas ces ressources.

L'image ci-dessous est tirée de Wikipédia :

Concorrência e paralelismo em Python

En interprétant l'image ci-dessus, nous pouvons extraire qu'un programme est enregistré sur disque (mémoire secondaire non volatile) et comprend plusieurs instructions, et peut être instancié (démarré) dans un ou plusieurs processus, et ceux-ci peuvent à leur tour avoir plusieurs fils de discussion associés.

Que signifient les liaisons E/S et CPU ?

Ces deux expressions apparaissent beaucoup dans la discussion sur la concurrence et peuvent apparaître en portugais avec I/O (entrée/sortie) et CPU (unité centrale de traitement).

Lorsque nous parlons de limites d'E/S et de CPU, nous parlons des facteurs limitants qui empêchent une opération de s'exécuter plus rapidement sur notre ordinateur, et nous pouvons trouver ces deux types d'opérations dans la même base de code.

Une opération liée au processeur est gourmande en ressources processeur et s'exécutera plus rapidement si le processeur est plus puissant. En d’autres termes, si nous passons de 2 GHz à 4 GHz, cette opération sera probablement plus rapide. On parle ici d'opérations qui effectuent de nombreux calculs, calculs ; par exemple, comment calculer Pi.

Une opération liée aux E/S dépend de la vitesse du réseau et de la vitesse des périphériques d'entrée et de sortie. Faire une requête à un serveur Web ou lire un fichier à partir du disque sont des opérations liées aux E/S.

Les deux types d'opérations peuvent bénéficier de l'utilisation de la concurrence.

Qu'est-ce que le GIL de Python ?

GIL signifie verrouillage global de l'interpréteur, qui vise à empêcher un processus Python d'exécuter plus d'un bytecode d'instruction Python en même temps. Pour exécuter un thread, il est nécessaire "d'acquérir" le GIL et pendant qu'un thread détient le GIL, un autre thread ne peut pas l'acquérir en même temps. Cela ne veut pas dire que nous ne pouvons pas avoir plus d'un fil de discussion dans ce contexte.

Nous envisageons ici l'implémentation de référence Python. CPython est l'implémentation standard de Python, utilisée comme référence pour le comportement du langage. Il existe d'autres implémentations, telles que Jython ou IronPython. GIL est présent dans CPython et ce n'est que récemment que nous avons eu un PEP (Python Enhancement Proposal) proposant de rendre GIL facultatif.

L'idée de GIL est d'éviter les conditions de concurrence, qui peuvent survenir lorsque plusieurs threads doivent référencer un objet Python en même temps. Si plusieurs threads modifient une variable partagée, cette variable peut se trouver dans un état inattendu. Image tirée du livre de Matthew Fowler :

Concorrência e paralelismo em Python

Dans l'image ci-dessus, deux threads tentent d'augmenter un nombre de références simultanément, et au lieu que le nombre donne 2, puisque les deux augmentent 1, le résultat final donne 1 (chaque thread est une colonne).

Qu'est-ce que la concurrence ?

La concurrence en informatique se produit lorsque s'occupe de plus d'une tâche, sans nécessairement exécuter ces deux tâches exactement en même temps. Une phrase bien connue de Rob Pyke sur le sujet :

La compétition signifie faire face à plusieurs choses en même temps. Le parallélisme consiste à faire plusieurs choses en même temps.

Pensez à cette situation hypothétique : si vous comptez réaliser deux gâteaux, vous pouvez commencer par préchauffer le four et, en attendant, préparer la pâte du premier gâteau. Une fois le four à bonne température, vous pouvez placer la pâte du premier gâteau au four et, en attendant que le gâteau lève au four, vous pouvez préparer la pâte du deuxième gâteau. L'idée de la compétition est fondamentalement la suivante, vous n'avez pas besoin d'être inactif, bloqué, arrêté, en attendant qu'une tâche soit terminée, vous pouvez faire un changer et changer de tâche.

Dans ce contexte nous avons deux types de multitâches :

  • Multitâche coopératif : dans ce modèle nous expliquons dans le code les points où les tâches peuvent être switch. En Python, cela est réalisé à l'aide d'une boucle d'événements, un modèle de conception commun, utilisant un seul thread et un seul cœur de processeur, en utilisant, par exemple, asyncio avec async et wait.
  • Multitâche préemptif : dans ce modèle, nous laissons le système d'exploitation gérer le switch. En Python, cela est réalisé avec plus d'un thread et un cœur de processeur en utilisant, par exemple, la bibliothèque de threads

L'image ci-dessous permet de résumer la concurrence en Python :

Concorrência e paralelismo em Python

Qu’est-ce que le parallélisme ?

Le parallélisme signifie que plusieurs tâches sont exécutées en même temps. En d’autres termes, le parallélisme implique la concurrence (traiter plusieurs tâches), mais la concurrence n’implique pas le parallélisme (les tâches ne sont pas nécessairement exécutées en parallèle au même moment). Pour que le parallélisme soit possible, nous avons besoin de plus d'un cœur de processeur.

En Python, le parallélisme est obtenu, par exemple, avec la bibliothèque multitraitement, où nous aurons plus d'un processus Python, chacun avec son propre GIL. L'image permet d'illustrer le parallélisme en Python :

Concorrência e paralelismo em Python

La bibliothèque asyncio

Il existe différentes manières d'obtenir la concurrence et le parallélisme en Python et nous pouvons utiliser certaines bibliothèques pour optimiser notre code, en fonction du type d'opération que nous traitons, liée aux E/S ou au CPU. asyncio est une lib pour obtenir la concurrence en utilisant async et wait. Extrait de la documentation :

Asyncio est utilisé comme base pour plusieurs frameworks Python asynchrones qui fournissent des serveurs réseau et Web hautes performances, des bibliothèques de connexion à des bases de données, des files d'attente de tâches distribuées, etc.

Comme vous pouvez l'imaginer, cette bibliothèque convient à l'optimisation des tâches liées aux E/S, où nous avons un temps d'attente réseau, d'écriture sur disque, etc. Dans une opération liée au CPU, il n'y a pas d'attente, nous dépendons uniquement de la vitesse de calcul du CPU.

La bibliothèque de threads

La bibliothèque de threads de Python nous permet d'exploiter plus d'un thread, cependant, nous avons toujours affaire à un cœur de processeur et à un processus Python, et rappelez-vous qu'il s'agit d'un cas de multitâche préemptif où le système d'exploitation le fait la tâche change pour nous. La bibliothèque est également plus utile pour optimiser les opérations liées aux E/S.

À propos du threading, le site Real Python fournit quelques points importants :

Étant donné que le système d'exploitation contrôle le moment où une tâche s'arrêtera et une autre tâche démarrera, toutes les données partagées entre les threads doivent être protégées, ou thread-safe. Malheureusement, request.Session() n'est pas thread-safe. Il existe plusieurs stratégies pour rendre l'accès aux données thread-safe en fonction de la nature des données et de la manière dont vous les utilisez. L'un d'eux consiste à utiliser des structures de données thread-safe comme file d'attente du module de file d'attente Python.

Nous avons trouvé la documentation sur la file d'attente ici.

La bibliothèque multitraitement

À propos de la bibliothèque multitraitement dans la documentation Python :

multiprocessing est un package qui prend en charge la génération de processus à l'aide d'une API similaire au module de threading. Le package multitraitement fournit une concurrence locale et distante, contournant efficacement le GIL en utilisant des sous-processus au lieu de threads. C'est pourquoi le module multitraitement permet au programmeur de profiter de plusieurs processeurs sur une seule machine.

Il convient de souligner que l'exécution de plus d'un processus sur différents cœurs de processeur ne signifie pas désactiver le GIL, mais plutôt que chaque processus aura son propre GIL. En tirant parti de plusieurs cœurs de processeur et en partageant de lourdes charges de travail de processeur entre plusieurs cœurs disponibles, la bibliothèque est plus adaptée aux contraintes de processeur.


Sources :

FOWLER, Matthieu. Concurrence Python avec asyncio. Publications Manning, 2022.

MACHADO, Francis Bérenger ; MAIA, Luiz Paulo. Architecture des systèmes d'exploitation : y compris des exercices avec le simulateur SOSIM et des questions ENADE. Rio de Janeiro : LTC, 2013.

Thread (informatique) par Wikipédia

Accélérez votre programme Python avec la concurrence par Real Python

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!

source:dev.to
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal