Python 中的同步和异步编程:关键概念和应用
同步编程
在同步编程中,任务是一个接一个地执行的。每项任务必须在下一项任务开始之前完成。这种线性方法很简单,但效率可能较低,尤其是在处理文件读取、网络请求或数据库查询等 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()
在此示例中,任务 1 必须在任务 2 开始之前完成。总执行时间是每个任务所花费时间的总和。
异步编程
异步编程允许多个任务同时运行,从而提高效率,特别是对于 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(例如 websockets 库)可以实现实时双向通信,从而实现高性能聊天应用程序、实时通知等。
数据处理管道:
- 同步:顺序处理大型数据集可能非常耗时。
- 异步:异步任务可以同时获取、处理和存储数据,显着减少处理时间。像 aiohttp 和 aiomysql 这样的库可用于异步 HTTP 请求和数据库操作。
网页抓取:
- 同步:顺序获取网页可能会很慢且效率低下。
- 异步:使用aiohttp进行异步HTTP请求可以同时获取多个网页,加快网页抓取过程。
文件I/O操作:
- 同步:顺序读取/写入大文件可能会阻塞其他操作。
- 异步:使用 aiofile 的异步文件 I/O 操作可以通过允许其他任务同时运行来提高性能。
同步和异步之间的选择
- 对 CPU 密集型任务使用同步编程,这些任务是计算密集型的,并且可以从顺序运行中受益。
- 对 I/O 密集型任务使用异步编程,其中操作涉及等待外部资源,例如网络请求、文件 I/O 或数据库查询。
实时消息应用示例
让我们创建一个基本的实时消息应用程序,使用 FastAPI 作为后端,使用 WebSockets 进行实时通信。我们将使用 Streamlit 作为前端来显示消息。
后端(FastAPI + WebSockets)
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)
- 安装依赖项:
pip install streamlit websocket-client
- 前端代码(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)
运行应用程序
- 启动FastAPI后端:
uvicorn backend:app
- 启动 Streamlit 前端:
streamlit run frontend.py
说明
后端(backend.py):
- FastAPI 应用程序在 /ws 处有一个 WebSocket 端点。
- ConnectionManager 处理 WebSocket 连接,向所有连接的客户端广播消息。
- 根端点 (/) 提供一个简单的 HTML 页面来测试 WebSocket 连接。
前端(frontend.py):
- Streamlit 应用程序连接到 WebSocket 服务器并侦听传入消息。
- 一个单独的线程处理 WebSocket 连接,以防止阻塞 Streamlit 应用程序。
- 用户可以通过输入框发送消息,消息会被发送到WebSocket服务器并显示在聊天中。
此示例演示了一个简单的实时消息应用程序,在后端使用 FastAPI 和 WebSockets,在前端使用 Streamlit。
以上是Python 中的同步和异步编程:关键概念和应用的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Linux终端中查看Python版本时遇到权限问题的解决方法当你在Linux终端中尝试查看Python的版本时,输入python...

使用FiddlerEverywhere进行中间人读取时如何避免被检测到当你使用FiddlerEverywhere...

在使用Python的pandas库时,如何在两个结构不同的DataFrame之间进行整列复制是一个常见的问题。假设我们有两个Dat...

Uvicorn是如何持续监听HTTP请求的?Uvicorn是一个基于ASGI的轻量级Web服务器,其核心功能之一便是监听HTTP请求并进�...

如何在10小时内教计算机小白编程基础?如果你只有10个小时来教计算机小白一些编程知识,你会选择教些什么�...

攻克Investing.com的反爬虫策略许多人尝试爬取Investing.com(https://cn.investing.com/news/latest-news)的新闻数据时,常常�...
