ホームページ  >  記事  >  バックエンド開発  >  Python での同期および非同期プログラミング: 主要な概念と応用

Python での同期および非同期プログラミング: 主要な概念と応用

WBOY
WBOYオリジナル
2024-08-31 06:03:37634ブラウズ

Synchronous and Asynchronous Programming in Python: Key Concepts and Applications

同期プログラミング
同期プログラミングでは、タスクが次々に実行されます。各タスクは、次のタスクが開始される前に完了する必要があります。この線形アプローチは単純ですが、特にファイル読み取り、ネットワーク リクエスト、データベース クエリなどの I/O バウンド操作を扱う場合は非効率になる可能性があります。

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()

この例では、タスク 2 が開始される前にタスク 1 が完了する必要があります。合計実行時間は、各タスクにかかった時間の合計です。

非同期プログラミング
非同期プログラミングでは、複数のタスクを同時に実行できるため、特に I/O バウンドのタスクの効率が向上します。 Python の asyncio ライブラリは、非同期プログラミングに必要なツールを提供します。

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())

この例では、task1 と task2 が同時に実行され、合計実行時間が最も長いタスクにかかる時間まで短縮されます。

潜在的なアプリケーション

Web サーバーと API:

  • 同期: Flask などの従来の Web フレームワークはリクエストを順番に処理します。これは、多数のリクエストを処理するときにボトルネックになる可能性があります。
  • 非同期: FastAPI や aiohttp などのフレームワークは、非同期プログラミングを使用して複数のリクエストを同時に処理し、スループットとパフォーマンスを向上させます。

リアルタイム メッセージング アプリケーション:

  • 同期: 各メッセージが順番に処理される場合、リアルタイム メッセージの処理に遅延が生じる可能性があります。
  • 非同期: 非同期処理 (WebSocket ライブラリなど) で WebSocket を使用すると、リアルタイムの双方向通信が可能になり、高性能のチャット アプリケーションやライブ通知などが可能になります。

データ処理パイプライン:

  • 同期: 大規模なデータセットを順番に処理すると時間がかかることがあります。
  • 非同期: 非同期タスクはデータを同時にフェッチ、処理、保存できるため、処理時間を大幅に短縮できます。 aiohttp や aiomysql などのライブラリは、非同期 HTTP リクエストやデータベース操作に使用できます。

ウェブスクレイピング:

  • 同期: Web ページを順次取得すると遅くなり、非効率になる可能性があります。
  • 非同期: 非同期 HTTP リクエストに aiohttp を使用すると、複数の Web ページを同時に取得でき、Web スクレイピング プロセスが高速化されます。

ファイル I/O 操作:

  • 同期: 大きなファイルの読み取り/書き込みを順番に行うと、他の操作がブロックされる可能性があります。
  • 非同期: aiofile を使用した非同期ファイル I/O 操作では、他のタスクを同時に実行できるため、パフォーマンスが向上します。

同期と非同期の選択

  • 演算負荷が高く、順次実行することでメリットが得られる CPU バウンドのタスクには、同期プログラミングを使用します。
  • ネットワーク リクエスト、ファイル I/O、データベース クエリなどの外部リソースの待機が操作に含まれる I/O バウンド タスクには、非同期プログラミングを使用します。

リアルタイムメッセージングアプリケーションの例
バックエンドには FastAPI を、リアルタイム通信には WebSocket を使用して、基本的なリアルタイム メッセージング アプリケーションを作成してみましょう。フロントエンドに Streamlit を使用してメッセージを表示します。

バックエンド (FastAPI + WebSocket)

1.依存関係をインストールします:
pip install fastapi uvicorn Websockets

2.バックエンドコード (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)

フロントエンド (Streamlit)

  1. 依存関係をインストールします:
pip install streamlit websocket-client
  1. フロントエンド コード (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)

アプリケーションの実行

  1. FastAPI バックエンドを開始します。
uvicorn backend:app
  1. Streamlit フロントエンドを起動します。
streamlit run frontend.py

説明
バックエンド (backend.py):

  • FastAPI アプリには /ws に WebSocket エンドポイントがあります。
  • ConnectionManager は WebSocket 接続を処理し、接続されているすべてのクライアントにメッセージをブロードキャストします。
  • ルート エンドポイント (/) は、WebSocket 接続をテストするための単純な HTML ページを提供します。

フロントエンド (frontend.py):

  • Streamlit アプリは WebSocket サーバーに接続し、受信メッセージをリッスンします。
  • Streamlit アプリのブロックを防ぐために、別のスレッドが WebSocket 接続を処理します。
  • ユーザーは入力ボックスを使用してメッセージを送信でき、メッセージは WebSocket サーバーに送信され、チャットに表示されます。

この例では、バックエンドに FastAPI と WebSocket、フロントエンドに Streamlit を使用したシンプルなリアルタイム メッセージング アプリケーションを示します。

以上がPython での同期および非同期プログラミング: 主要な概念と応用の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。