Maison >développement back-end >Tutoriel Python >Programmation synchrone et asynchrone en Python : concepts clés et applications

Programmation synchrone et asynchrone en Python : concepts clés et applications

WBOY
WBOYoriginal
2024-08-31 06:03:37685parcourir

Synchronous and Asynchronous Programming in Python: Key Concepts and Applications

Programmation Synchrone
En programmation synchrone, les tâches sont exécutées les unes après les autres. Chaque tâche doit être terminée avant que la suivante ne commence. Cette approche linéaire est simple mais peut s'avérer inefficace, en particulier lorsqu'il s'agit d'opérations liées aux E/S telles que la lecture de fichiers, les requêtes réseau ou les requêtes de base de données.

import time

def task1():
    print("Starting task 1...")
    time.sleep(2)
    print("Task 1 completed")

def task2():
    print("Starting task 2...")
    time.sleep(2)
    print("Task 2 completed")

def main():
    task1()
    task2()

if __name__ == "__main__":
    main()

Dans cet exemple, la tâche 1 doit être terminée avant le démarrage de la tâche 2. Le temps total d'exécution est la somme du temps pris par chaque tâche.

Programmation asynchrone
La programmation asynchrone permet à plusieurs tâches de s'exécuter simultanément, améliorant ainsi l'efficacité, en particulier pour les tâches liées aux E/S. La bibliothèque asyncio de Python fournit les outils nécessaires à la programmation asynchrone.

import asyncio

async def task1():
    print("Starting task 1...")
    await asyncio.sleep(2)
    print("Task 1 completed")

async def task2():
    print("Starting task 2...")
    await asyncio.sleep(2)
    print("Task 2 completed")

async def main():
    await asyncio.gather(task1(), task2())

if __name__ == "__main__":
    asyncio.run(main())

Dans cet exemple, la tâche 1 et la tâche 2 s'exécutent simultanément, réduisant le temps d'exécution total au temps pris par la tâche la plus longue.

Applications potentielles

Serveurs Web et API :

  • Synchronique : les frameworks Web traditionnels comme Flask gèrent les requêtes de manière séquentielle. Cela peut constituer un goulot d'étranglement lors du traitement d'un grand nombre de demandes.
  • Asynchrone : des frameworks comme FastAPI et aiohttp utilisent la programmation asynchrone pour gérer plusieurs requêtes simultanément, améliorant ainsi le débit et les performances.

Applications de messagerie en temps réel :

  • Synchrone : le traitement des messages en temps réel peut entraîner des retards si chaque message est traité séquentiellement.
  • Asynchrone : l'utilisation de WebSockets avec une gestion asynchrone (par exemple, une bibliothèque Websockets) permet une communication bidirectionnelle en temps réel, permettant des applications de chat hautes performances, des notifications en direct, etc.

Pipelines de traitement des données :

  • Synchrone : le traitement séquentiel de grands ensembles de données peut prendre beaucoup de temps.
  • Asynchrone : les tâches asynchrones peuvent récupérer, traiter et stocker des données simultanément, ce qui réduit considérablement le temps de traitement. Des bibliothèques comme aiohttp et aiomysql peuvent être utilisées pour les requêtes HTTP asynchrones et les opérations de base de données.

Grattage Web :

  • Synchrone : la récupération séquentielle de pages Web peut être lente et inefficace.
  • Asynchrone : l'utilisation d'aiohttp pour les requêtes HTTP asynchrones peut récupérer plusieurs pages Web simultanément, accélérant ainsi le processus de scraping Web.

Opérations d'E/S sur les fichiers :

  • Synchronisé : la lecture/écriture séquentielle de gros fichiers peut bloquer d'autres opérations.
  • Asynchrone : les opérations d'E/S de fichiers asynchrones utilisant des fichiers aiofiles peuvent améliorer les performances en permettant à d'autres tâches de s'exécuter simultanément.

Choisir entre synchrone et asynchrone

  • Utilisez la programmation synchrone pour les tâches liées au processeur où les opérations nécessitent beaucoup de calculs et bénéficient d'une exécution séquentielle.
  • Utilisez la programmation asynchrone pour les tâches liées aux E/S où les opérations impliquent l'attente de ressources externes, telles que les requêtes réseau, les E/S de fichiers ou les requêtes de base de données.

Exemple d'application de messagerie en temps réel
Créons une application de messagerie de base en temps réel en utilisant FastAPI pour le backend et WebSockets pour la communication en temps réel. Nous utiliserons Streamlit pour le frontend afin d'afficher les messages.

Backend (FastAPI + WebSockets)

1.Installer les dépendances :
pip installe les websockets fastapi uvicorn

2.Code backend (backend.py) :

from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponse
from typing import List

app = FastAPI()

class ConnectionManager:
    def __init__(self):
        self.active_connections: List[WebSocket] = []

    async def connect(self, websocket: WebSocket):
        await websocket.accept()
        self.active_connections.append(websocket)

    def disconnect(self, websocket: WebSocket):
        self.active_connections.remove(websocket)

    async def send_message(self, message: str):
        for connection in self.active_connections:
            await connection.send_text(message)

manager = ConnectionManager()

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await manager.connect(websocket)
    try:
        while True:
            data = await websocket.receive_text()
            await manager.send_message(data)
    except WebSocketDisconnect:
        manager.disconnect(websocket)

@app.get("/")
async def get():
    return HTMLResponse("""
    <!DOCTYPE html>
    <html>
    <head>
        <title>Chat</title>
    </head>
    <body>
        <h1>WebSocket Chat</h1>
        <form action="" onsubmit="sendMessage(event)">
            <input type="text" id="messageText" autocomplete="off"/>
            <button>Send</button>
        </form>
        <ul id='messages'>
        </ul>
        <script>
            var ws = new WebSocket("ws://localhost:8000/ws");
            ws.onmessage = function(event) {
                var messages = document.getElementById('messages');
                var message = document.createElement('li');
                message.appendChild(document.createTextNode(event.data));
                messages.appendChild(message);
            };

            function sendMessage(event) {
                var input = document.getElementById("messageText");
                ws.send(input.value);
                input.value = '';
                event.preventDefault();
            }
        </script>
    </body>
    </html>
    """)

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

Frontend (Streamlit)

  1. Installer les dépendances :
pip install streamlit websocket-client
  1. Code frontal (frontend.py) :
import streamlit as st
import asyncio
import threading
from websocket import create_connection, WebSocket

st.title("Real-time Messaging Application")

if 'messages' not in st.session_state:
    st.session_state.messages = []

def websocket_thread():
    ws = create_connection("ws://localhost:8000/ws")
    st.session_state.ws = ws
    while True:
        message = ws.recv()
        st.session_state.messages.append(message)
        st.experimental_rerun()

if 'ws' not in st.session_state:
    threading.Thread(target=websocket_thread, daemon=True).start()

input_message = st.text_input("Enter your message:")

if st.button("Send"):
    if input_message:
        st.session_state.ws.send(input_message)
        st.session_state.messages.append(f"You: {input_message}")

st.subheader("Chat Messages:")
for message in st.session_state.messages:
    st.write(message)

Exécuter l'application

  1. Démarrez le backend FastAPI :
uvicorn backend:app
  1. Démarrez l'interface Streamlit :
streamlit run frontend.py

Explication
Back-end (backend.py) :

  • L'application FastAPI possède un point de terminaison WebSocket à l'adresse /ws.
  • ConnectionManager gère les connexions WebSocket et diffuse les messages à tous les clients connectés.
  • Le point de terminaison racine (/) sert une simple page HTML pour tester la connexion WebSocket.

Frontend (frontend.py) :

  • L'application Streamlit se connecte au serveur WebSocket et écoute les messages entrants.
  • Un fil de discussion distinct gère la connexion WebSocket pour éviter de bloquer l'application Streamlit.
  • Les utilisateurs peuvent envoyer des messages à l'aide de la zone de saisie, qui sont ensuite envoyés au serveur WebSocket et affichés dans le chat.

Cet exemple montre une application simple de messagerie en temps réel utilisant FastAPI et WebSockets pour le backend et Streamlit pour le frontend.

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:
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