Maison > Article > développement back-end > Concurrence en Python avec threading et multitraitement
La concurrence est une idée cruciale dans la programmation moderne qui permet à plusieurs tâches de s'exécuter en même temps pour améliorer les performances des applications.
Il existe plusieurs façons d'obtenir la concurrence en Python, le threading et le multitraitement étant les plus connus.
Dans cet article, nous explorerons ces deux méthodes en détail, comprendrons comment elles fonctionnent et discuterons du moment où les utiliser, ainsi que des exemples de code pratiques.
Avant de parler de threading et de multitraitement, il est important de comprendre ce que signifie la concurrence.
La simultanéité, c'est lorsqu'un programme peut effectuer plusieurs tâches ou processus en même temps.
Cela peut permettre au programme de mieux utiliser les ressources et de s'exécuter plus rapidement, en particulier lorsqu'il doit effectuer des tâches telles que lire des fichiers ou effectuer de nombreux calculs.
Il existe deux manières principales d'obtenir la simultanéité :
Python propose deux manières principales d'obtenir la simultanéité :
Le threading vous permet d'exécuter plusieurs unités plus petites d'un processus, appelées threads, au sein du même processus, partageant le même espace mémoire.
Les threads sont plus légers que les processus et la commutation entre eux est plus rapide.
Cependant, le threading en Python est soumis au Global Interpreter Lock (GIL), qui garantit qu'un seul thread peut exécuter du code Python à la fois.
Le module de threading de Python offre un moyen simple et flexible de créer et de gérer des threads.
Commençons par un exemple simple :
import threading import time def print_numbers(): for i in range(5): print(f"Number: {i}") time.sleep(1) # Creating a thread thread = threading.Thread(target=print_numbers) # Starting the thread thread.start() # Wait for the thread to complete thread.join() print("Thread has finished executing") # Output: # Number: 0 # Number: 1 # Number: 2 # Number: 3 # Number: 4 # Thread has finished executing
Dans cet exemple :
Le threading est particulièrement utile pour les tâches liées aux E/S, telles que les opérations sur les fichiers, les requêtes réseau ou les requêtes de base de données, où le programme passe la plupart de son temps à attendre des ressources externes.
Voici un exemple qui simule le téléchargement de fichiers à l'aide de threads :
import threading import time def download_file(file_name): print(f"Starting download of {file_name}...") time.sleep(2) # Simulate download time print(f"Finished downloading {file_name}") files = ["file1.zip", "file2.zip", "file3.zip"] threads = [] # Create and start threads for file in files: thread = threading.Thread(target=download_file, args=(file,)) thread.start() threads.append(thread) # Ensure all threads have finished for thread in threads: thread.join() print("All files have been downloaded.") # Output: # Starting download of file1.zip... # Starting download of file2.zip... # Starting download of file3.zip... # Finished downloading file1.zip # Finished downloading file2.zip # Finished downloading file3.zip # All files have been downloaded.
En créant et en gérant des threads distincts pour chaque téléchargement de fichier, le programme peut gérer plusieurs tâches simultanément, améliorant ainsi l'efficacité globale.
Les étapes clés du code sont les suivantes :
Bien que le threading puisse améliorer les performances des tâches liées aux E/S, il présente des limites :
Le multitraitement résout les limites du threading en utilisant des processus distincts au lieu de threads.
Chaque processus possède son propre espace mémoire et son interpréteur Python, permettant un véritable parallélisme sur les systèmes multicœurs.
Cela rend le multitraitement idéal pour les tâches qui nécessitent des calculs lourds.
Le module multitraitement en Python vous permet de créer et de gérer facilement des processus.
Let’s start with a basic example:
import multiprocessing import time def print_numbers(): for i in range(5): print(f"Number: {i}") time.sleep(1) if __name__ == "__main__": # Creating a process process = multiprocessing.Process(target=print_numbers) # Starting the process process.start() # Wait for the process to complete process.join() print("Process has finished executing") # Output: # Number: 0 # Number: 1 # Number: 2 # Number: 3 # Number: 4 # Process has finished executing
This example is similar to the threading example, but with processes.
Notice that the process creation and management are similar to threading, but because processes run in separate memory spaces, they are truly concurrent and can run on different CPU cores.
Multiprocessing is particularly beneficial for tasks that are CPU-bound, such as numerical computations or data processing.
Here’s an example that calculates the square of numbers using multiple processes:
import multiprocessing def compute_square(number): return number * number if __name__ == "__main__": numbers = [1, 2, 3, 4, 5] # Create a pool of processes with multiprocessing.Pool() as pool: # Map function to numbers using multiple processes results = pool.map(compute_square, numbers) print("Squares:", results) # Output: # Squares: [1, 4, 9, 16, 25]
Here are the key steps in the code:
Since each process has its own memory space, sharing data between processes requires inter-process communication (IPC) mechanisms.
The multiprocessing module provides several tools for IPC, such as Queue, Pipe, and Value.
Here’s an example using Queue to share data between processes:
import multiprocessing def worker(queue): # Retrieve and process data from the queue while not queue.empty(): item = queue.get() print(f"Processing {item}") if __name__ == "__main__": queue = multiprocessing.Queue() # Add items to the queue for i in range(10): queue.put(i) # Create a pool of processes to process the queue processes = [] for _ in range(4): process = multiprocessing.Process(target=worker, args=(queue,)) processes.append(process) process.start() # Wait for all processes to complete for process in processes: process.join() print("All processes have finished.") # Output: # Processing 0 # Processing 1 # Processing 2 # Processing 3 # Processing 4 # Processing 5 # Processing 6 # Processing 7 # Processing 8 # Processing 9 # All processes have finished.
In this example:
While multiprocessing provides true parallelism, it comes with its own set of challenges:
Choosing between threading and multiprocessing depends on the type of task you're dealing with:
Use Threading:
Use Multiprocessing:
Concurrency in Python is a powerful way to make your applications run faster.
Threading is great for tasks that involve a lot of waiting, like network operations or reading/writing files, but it's not as effective for tasks that require heavy computations because of something called the Global Interpreter Lock (GIL).
On the other hand, multiprocessing allows for true parallelism, making it perfect for CPU-intensive tasks, although it comes with higher overhead and complexity.
Que vous traitiez des données, traitiez plusieurs requêtes réseau ou effectuiez des calculs complexes, les outils de threading et de multitraitement de Python vous offrent ce dont vous avez besoin pour rendre votre programme aussi efficace et rapide que possible.
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!