52、【Ubuntu】【Gitlab】拉出内网 Web 服务:http.server 单/多线程分析(四)

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

上篇 blog
【Ubuntu】【Gitlab】拉出内网 Web 服务:http.server 单/多线程分析(三)

分析了 Python http.server 在多线程下并发处理 TCP 网络请求的极限,下面继续

Python http.server 单/多线程分析

OK,前面都是从线程的角度,分析 Python http.server 模块不能支持高并发,下面再补充下,从进程的角度看这个事情

首先,Python 是一个解释型语言,当在终端输入

bash 复制代码
python3 -m http.server 2025

这样一个命令尝试运行 Python 程序时,操作系统会为这个程序创建一个进程 ,这个进程将使用 CPython(Python 解释器,前面的 C 表示解释器是用 C 语言写的 ) 来把 *.py 文件编译成字节码并执行

然后这里关键点来了,运行 Python 命令时,操作系统启动一个新进程,相当于一个 Python 程序等于一个进程,在这个进程中,可以有多个线程,但这些线程之间会受到 GIL (全称 Global Interpreter Lock,全局解释器锁)的限制

比如运行完 python3 -m http.server 2025 之后,在终端输入

bash 复制代码
ps aux | grep http.server

可以看到 Python 启动的 Web 服务进程,这个进程使用了 2025 端口对外提供服务,对进程来说,进程是操作系统分配资源的基本单位,正常情况下,一个带有多线程的进程可以同时使用多个 CPU 核心,达到并行执行的效果

但对于 Python 程序而言,CPython 解释器在工作时,需要在 GIL(全局解释器锁)机制下才能正常运行,GIL 会确保同一时刻,只有一个线程能够执行 Python 字节码,所以,即使机器是多核的,在一个 Python 进程内,http.server 即使开了多线程,在执行纯 Python 代码时,也只能轮流使用 1 个 CPU 核心,无法真正并行

GIL 的工作流程大致如下:

  • 整个 CPython 进程只有一把 GIL 锁
  • 任何线程想执行 Python 字节码必须先获取 GIL 锁
  • 如果 GIL 锁被其他线程占着,那么当前线程只能等待

所以即使有 16 个线程,16 个 CPU 核心,同一时刻也只有 1 个线程在跑 Python 代码,因为整个 CPython 进程只有一把 GIL 锁,这就好比一个厨房(Python 进程)里,有 16 个厨师(线程),但只有一把菜刀(GIL 锁),谁想切菜(执行 Python 代码),必须拿到菜刀,这个厨师在切菜的时候,其他厨师就只能干站着等(因为没菜刀了),再多厨师也快不起来

Python 官方(https://docs.python.org/3/library/threading.html)对这块儿的描述如下

OK,下面再分析下多线程的并发行为,之前 blog 【Ubuntu】【Gitlab】拉出内网 Web 服务:http.server 单/多线程分析(二) 说过,开启多线程后,两个 Web 请求等待的时间基本是相同的,因为当线程执行 IO 操作,比如 time.sleep(),socket.recv(),file.read()时,线程会主动释放 GIL 锁 ,因为这些 IO 操作是耗时的,操作系统要去处理磁盘,或者网络任务,在这段时间 Python 解释器就可以闲下来不干活,也就没必要一直占着 GIL 锁,此时该 Python 进程内的其他线程就可以趁机获取 GIL,去执行自己的 Python 代码

所以 Python 的多线程是否有用,得分情况:

  • 对于 IO 密集型任务(比如 Web 服务器):多线程是有效的,因为大部分时间在等 IO
  • 对于 CPU 密集型任务(比如循环计算,图像处理等):多线程就没有用了,因为要一直抢 GIL 锁

OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog
【Ubuntu】【Gitlab】拉出内网 Web 服务:http.server 单/多线程分析(五)

相关推荐
CCblandy11 小时前
HTTP 长连接 3 类故障实测:[WinError 10053]、99 个 TIME_WAIT、69 次多余握手,4 种对策怎么选
后端·python·网络协议·http·云原生·性能优化·架构
31087487616 小时前
0028.配置windows的共享目录让ubuntu使用
ubuntu·windows共享文件夹
这个人懒得名字都没写18 小时前
Ubuntu 24.04修改源
ubuntu
隐擎fox19 小时前
深入 QUIC 与 HTTP/3 协议栈特征:新一代 UDP 流量风控识别与网络防关联工程实战
网络·http·udp
承渊政道20 小时前
Linux网络学习【TCP Socket编程实战:connect的断线重连与客户端访问Linux验证】
linux·网络·学习·ubuntu·tcp·socket编程
玖石书1 天前
Ubuntu 24.04 UFW 全命令攻略:从入门到端口开放实战
linux·运维·ubuntu
夏尔Gaesar1 天前
解决Ubuntu安装vm tools时选项为灰色问题
ubuntu
墨神谕2 天前
RPC框架与HTTP REST的区别
网络协议·http·rpc
HY小宝F2 天前
树莓派智能摄像头系统 30 天重学计划之 Day 04 · HTTP / API:控制链入口 —— 学习总结
网络协议·学习·http
蜗牛互联网2 天前
Java标准HTTP调用多模态模型的票据抽取前置校验
java·人工智能·python·http