You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python多线程搭配非异步requests库为何高效?

Python线程+requests实现近似并行的原理与解决方案

核心原理解释

关于GIL的误区

Python的GIL(全局解释器锁)确实限制同一时刻只有一个线程执行Python字节码,但当线程遇到阻塞式IO操作时(比如网络请求、文件读写),解释器会主动释放GIL,让其他线程获得执行权。你的场景中,每个线程发起请求后,大部分时间都在等待服务器响应(这是IO阻塞,而非CPU计算),此时GIL被释放,其他线程可以立刻发起自己的请求,所以三个请求几乎同时进行,总耗时仅略超5秒。

阻塞式requests的适配性

requests是阻塞式库,但这里的“阻塞”指线程在等待IO结果时会暂停,而非占用CPU资源。正因为这种IO阻塞会触发GIL释放,多线程可以在IO等待期间切换执行,实现近似并行的效果——这正是线程处理IO密集型任务的核心优势。

可查阅的参考资料

  • Python官方文档中threading模块的说明,重点关注GIL与IO操作的交互逻辑
  • 《Python Cookbook》中“使用线程处理IO密集型任务”相关章节
  • Python官方GIL技术文档,了解GIL的设计初衷与释放机制
  • requests官方文档,明确其阻塞式IO的工作模式

继续使用线程的建议

你的场景属于典型的IO密集型任务,完全不需要切换到异步库。可以通过以下方式优化现有代码:

  • 使用concurrent.futures.ThreadPoolExecutor替代手动创建Thread对象,更方便管理线程池,减少代码冗余
  • 控制线程池的max_workers数量,避免创建过多线程导致资源浪费(对于网络请求,通常设置为CPU核心数的2-5倍即可)

示例代码:

from concurrent.futures import ThreadPoolExecutor
import requests

def get_response(url):
    resp = requests.get(url)
    return (url, resp.status_code)

target_urls = ["https://your-wait-5s-url.com"] * 3

# 用线程池执行请求
with ThreadPoolExecutor(max_workers=3) as executor:
    results = executor.map(get_response, target_urls)

for url, status in results:
    print(f"{url} 响应状态码: {status}")

内容的提问来源于stack exchange,提问作者StefanH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 17:03:12