llm python web框架的使用(同步/异步/进程/线程/协程)
异步与同步 执行流式输出
from fastapi import FastAPI import asyncio from langchain_openai import ChatOpenAI app = FastAPI() llm = ChatOpenAI(streaming=True) # 同步端点 - 不适合高并发 @app.post("/chat-sync") def chat_sync(question: str): """同步端点 - 每个请求阻塞线程""" messages = [HumanMessage(content=question)] response = llm.invoke(messages) # 阻塞调用 return {"response": response.content} # 异步端点 - 适合高并发 @app.post("/chat-async") async def chat_async(question: str): """异步端点 - 非阻塞处理""" messages = [HumanMessage(content=question)] # 流式响应 async def generate_stream(): full_content = "" async for chunk in llm.astream(messages): if hasattr(chunk, 'content'): content = chunk.content full_content += content yield f"data: {content}\n\n" return StreamingResponse(generate_stream(), media_type="text/plain") # 测试并发性能 @app.get("/stress-test") async def stress_test(): """压力测试端点""" start_time = time.time() # 同时处理50个模拟请求 async def mock_request(req_id): await asyncio.sleep(1) # 模拟处理时间 return f"Response-{req_id}" tasks = [mock_request(i) for i in range(50)] results = await asyncio.gather(*tasks) end_time = time.time() return { "total_requests": len(results), "total_time": end_time - start_time, "requests_per_second": len(results) / (end_time - start_time) }
优缺点:
| 方面 | 同步多线程 | 异步单线程 |
|---|---|---|
| 内存使用 | 每个线程8MB+ | 共享内存,极少开销 |
| CPU效率 | 大量上下文切换 | 几乎没有上下文切换 |
| 并发能力 | 受线程数限制 | 理论上无限 |
| 代码复杂度 | 简单直观 | 需要理解异步概念 |
| IO密集型 | 性能差 | 性能极佳 |
| CPU密集型 | 性能好 | 性能差(应用场景不同) |
1. 同步编程 (Synchronous Programming)
基本概念
-
执行模式:顺序执行,阻塞式
-
控制流:直线型,一步完成再执行下一步
-
资源占用:单线程执行
优点
-
✅ 简单直观:代码逻辑清晰,易于理解和调试
-
✅ 可预测性:执行顺序明确,不存在竞态条件
-
✅ 开发效率:编写和测试相对简单
-
✅ 错误处理:异常传播直接,堆栈信息完整
缺点
-
❌ 性能低下:IO操作时CPU空闲,资源利用率低
-
❌ 扩展性差:无法充分利用多核CPU
-
❌ 并发能力弱:难以处理大量并发请求
-
❌ 响应性差:长时间操作会阻塞整个程序
适用场景
-
IO密集型任务
-
GUI应用程序
-
网络请求处理
-
数据库操作
2. 多线程编程 (Multithreading)
基本概念
-
执行模式:并发执行,共享内存
-
资源模型:多个线程共享进程资源
-
Python特性:受GIL限制
优点
-
✅ IO性能提升:IO等待时可切换线程
-
✅ 资源共享:线程间通信简单
-
✅ 响应性:不会完全阻塞程序
-
✅ 开发相对简单:比多进程更容易
缺点
-
❌ GIL限制:Python中无法真正并行执行CPU任务
-
❌ 线程安全:需要处理竞态条件和锁
-
❌ 调试困难:问题难以复现和定位
-
❌ 资源开销:每个线程需要独立栈空间
适用场景
-
IO密集型任务
-
GUI应用程序
-
网络请求处理
-
数据库操作
3. 多进程编程 (Multiprocessing)
基本概念
-
执行模式:并行执行,独立内存空间
-
资源模型:进程间资源隔离
-
Python特性:绕过GIL限制
优点
-
✅ 真正并行:充分利用多核CPU
-
✅ 内存安全:进程崩溃不影响其他进程
-
✅ 绕过GIL:CPU密集型任务性能最佳
-
✅ 资源隔离:避免意外干扰
缺点
-
❌ 资源开销大:进程创建和销毁成本高
-
❌ 通信复杂:进程间通信需要特殊机制
-
❌ 内存占用:每个进程有独立内存空间
-
❌ 启动较慢:进程初始化需要时间
适用场景
-
CPU密集型计算
-
科学计算和数据处理
-
需要高稳定性的任务
-
充分利用多核CPU的场景
4. 异步编程/协程 (Asynchronous/Coroutine)
基本概念
-
执行模式:单线程事件循环,非阻塞
-
控制机制:协程挂起和恢复
-
资源模型:极轻量级的"微线程"
优点
-
✅ 超高并发:单线程可处理数万并发连接
-
✅ 资源高效:内存开销极小,无上下文切换成本
-
✅ 性能卓越:IO密集型任务性能最佳
-
✅ 代码清晰:async/await语法类似同步代码
缺点
-
❌ 学习曲线:需要理解事件循环和异步概念
-
❌ CPU限制:不适合CPU密集型任务
-
❌ 生态依赖:需要异步兼容的库
-
❌ 调试复杂:异步堆栈跟踪较复杂
适用场景
-
高并发网络应用
-
Web服务器和API服务
-
实时数据处理
-
微服务架构
5. 全面对比总结
执行特性对比
| 模型 | 并行能力 | 内存开销 | 启动速度 | 通信成本 |
|---|---|---|---|---|
| 同步 | 无 | 最低 | 最快 | 无 |
| 多线程 | 伪并行(受GIL) | 中等 | 快 | 低 |
| 多进程 | 真并行 | 最高 | 慢 | 高 |
| 异步 | 并发(单线程) | 最低 | 快 | 无 |
资源消耗对比
| 模型 | CPU利用率 | 内存效率 | 上下文切换 | 可扩展性 |
|---|---|---|---|---|
| 同步 | 低 | 高 | 无 | 差 |
| 多线程 | 中 | 中 | 中 | 中 |
| 多进程 | 高 | 低 | 高 | 高 |
| 异步 | 极高 | 极高 | 极低 | 极高 |
6. 技术选型指南
根据任务类型选择
CPU密集型任务(数学计算、图像处理、数据分析):
-
🥇 首选:多进程
-
🥈 次选:同步(如果并发要求不高)
-
❌ 避免:多线程(受GIL限制)、异步(无优势)
IO密集型任务(网络请求、文件读写、数据库操作):
-
🥇 首选:异步/协程
-
🥈 次选:多线程
-
❌ 避免:同步(性能差)
高并发网络应用(Web服务器、API网关、实时通信):
-
🥇 唯一选择:异步/协程
-
❌ 避免:其他模型(无法满足性能要求)
混合型任务:
-
🥇 推荐:组合使用(如多进程 + 异步)
-
💡 策略:进程处理CPU任务,异步处理IO任务
根据项目规模选择
小型项目/工具:
-
同步编程(简单直接)
-
多线程(如果需要基本并发)
中型项目/服务:
-
多线程(平衡复杂度和性能)
-
异步编程(如果需要高并发)
大型分布式系统:
-
异步编程(核心服务)
-
多进程(计算密集型组件)
-
组合架构(微服务+异步)

浙公网安备 33010602011771号