游戏百科

Python 3.14入门并发提速实战:GIL真能“关灯”了,顺手做个前端/鸿蒙都能调的压缩小接口

兄弟姐妹们,打工人最怕啥?不是代码写不出来,是“环境一装半天、跑起来还慢、上线还踩坑”。我这两天翻了下 Python 3

兄弟姐妹们,打工人最怕啥?不是代码写不出来,是“环境一装半天、跑起来还慢、上线还踩坑”。我这两天翻了下 Python 3.14.2(2025-12-05) 的发布信息,心里就一个感受:这回官方是真想让大家少折腾,多干活。 你看它这波更新,别的先不说,光是这几条就够咱们茶水间吹一下午:

Free-threaded(可选无GIL):线程终于有机会把多核吃满,不再是“多线程看着热闹、CPU却在打哈欠”。

标准库自带 Zstandard(zstd)压缩:以前你想要又快又省的压缩,得装第三方;现在官方直接塞进来了。

新规矩:3.14 起不再提供 PGP 签名,官方推荐 Sigstore:说白了就是“验包方式换了”,别再用老习惯去找 PGP 了。

今天咱不写论文、不摆架子,直接来个能复制就跑的入门实战:做一个“压缩小卖部”接口——后端用 Python 3.14 的 compression.zstd,前端一个 HTML 直接调,最后再给你补一段 鸿蒙 ArkTS 调接口的写法。你写完这套,回头跟同事说一句:“这接口我十分钟起的”,气势立马不一样。

入门技术

先把话说明白:Python 3.14 的“无GIL”不是默认所有人都自动起飞。它是一个“free-threaded build”(特殊构建),从 Python 3.13 开始就能玩了,3.14 是“官方支持、但仍然可选”的阶段。怎么判断你现在这个 Python 到底是不是那种“能关 GIL 的版本”?官方给了很实在的办法:python -VV / sys.version 里会出现 free-threading build,还能用 sys._is_gil_enabled() 看进程里 GIL 到底开没开。另外,你想临时开/关 GIL,也不是靠玄学——有标准姿势:

PYTHON_GIL=1 强制开 GILPYTHON_GIL=0 强制关 GIL(前提:你得是 --disable-gil 那种构建)或者启动时用 -X gil=0,1

还有一点特别“人间真实”:free-threaded 不是白嫖,单线程会有点额外开销;官方文档说 pyperformance 平均开销大概在 1%~8%(跟平台有关)。所以别一上来就喊“我项目必须全换”,先挑你真正 CPU 吃紧的地方上。

主内容

先把环境整利索:用 uv 把“装环境”这破事儿干脆利落解决

以前新人入门最烦的就是:

“装 Python → 装 pip → 装 venv → 装依赖 → 版本还对不上 → 人直接麻了”。

现在我强烈建议你试试 uv,它就是那种“少废话,多办事”的工具:一个工具把 pip/venv/装 Python/锁依赖这些活儿都包了,还主打一个快。

终端里你就这么敲(照抄就行):

# 装 uv(官方写法)curl -LsSf https://astral.sh/uv/install.sh | sh# 新建项目uv init zstd-shopcd zstd-shop# 安装/切到 Python 3.14(你机器上没装也没事,uv 会管)uv python install 3.14uv python pin 3.14# 装依赖:FastAPI + Uvicornuv add fastapi "uvicorn[standard]"

上面这些命令,基本就是“给你把地基打好”。uv 官方文档就这么干的:能初始化项目、加依赖、跑命令、还能装 Python 版本。

后端开干:用 Python 3.14 自带 zstd 写压缩/解压 API

Python 3.14 新增的 compression.zstd 模块,最爽的是:它既有一把梭的 compress/decompress,也有文件接口、流式压缩这些正经家伙。

注意它属于“可选模块”,极少数发行版可能没编进去;要是你 import 报错,优先换官方安装包/正规构建。

在项目根目录新建 app.py,直接贴:

from __future__ import annotationsimport base64import osimport sysimport timefrom concurrent.futures import ThreadPoolExecutorfrom fastapi import FastAPIfrom pydantic import BaseModel# Python 3.14 新东西:标准库自带 zstdfrom compression import zstd  # 需要 Python 3.14+app = FastAPI(title="Zstd Shop (Python 3.14)")class CompressIn(BaseModel):    text: str    level: int | None = 3  # 压缩等级:越大越省空间但越慢;3 先够用class DecompressIn(BaseModel):    b64: str@app.get("/ping")def ping():    return {        "ok": True,        "python": sys.version,        # 有 free-threaded build 才可能关 GIL;普通 Python 这里永远是 True        "gil_enabled": getattr(sys, "_is_gil_enabled", lambda: True)(),    }@app.post("/compress")def compress_api(payload: CompressIn):    raw = payload.text.encode("utf-8")    compressed = zstd.compress(raw, level=payload.level)    b64 = base64.b64encode(compressed).decode("ascii")    ratio = (len(compressed) / len(raw)) if raw else 0.0    return {        "bytes_in": len(raw),        "bytes_out": len(compressed),        "ratio": round(ratio, 4),        "b64": b64,    }@app.post("/decompress")def decompress_api(payload: DecompressIn):    compressed = base64.b64decode(payload.b64.encode("ascii"))    raw = zstd.decompress(compressed)    return {"text": raw.decode("utf-8", errors="replace")}# 纯 Python CPU 压力测试:看看线程到底能不能真并行(free-threaded 才会明显)def cpu_burn(iters: int) -> int:    x = 0    for i in range(iters):        x ^= (i * 2654435761) & 0xFFFFFFFF        x = ((x << 13) | (x >> 19)) & 0xFFFFFFFF    return x@app.get("/bench")def bench(workers: int = 4, iters: int = 25_000_00):    start = time.perf_counter()    with ThreadPoolExecutor(max_workers=workers) as ex:        results = list(ex.map(cpu_burn, [iters] * workers))    cost = time.perf_counter() - start    return {        "workers": workers,        "iters_per_worker": iters,        "seconds": round(cost, 4),        "checksum": sum(results) & 0xFFFFFFFF,        "gil_enabled": getattr(sys, "_is_gil_enabled", lambda: True)(),        "cpu_count": os.cpu_count(),        "python": sys.version,    }

你看这代码,就干三件事:

“能压就压、能解就解、顺手给你一个 bench 看看线程有没有真跑起来”。

启动服务:

uv run uvicorn app:app --reload --host 0.0.0.0 --port 8000

浏览器打开 http://127.0.0.1:8000/docs,FastAPI 自带的接口文档就出来了。

这就是我喜欢 FastAPI 的地方:新手也能“像样儿”。

端一口气接上:一个 HTML 就能把接口玩起来

同目录新建 index.html,内容如下(不搞框架,先求能跑):

<!doctype html><html lang="zh">  <head>    <meta charset="utf-8" />    <title>Zstd Shop Demo</title>  </head>  <body>    <h2>压缩小卖部(Python 3.14 zstd)</h2>    <p>随便粘一段文字进去,点压缩,看体积能省多少。</p>    <textarea id="txt" style="width: 100%; height: 140px;">打工人记住:工具选对,效率翻倍。</textarea>    <div style="margin: 10px 0;">      <button id="btnC">压缩</button>      <button id="btnD">解压</button>      <button id="btnB">跑个并发 bench</button>    </div>    <pre id="out" style="background:#f6f6f6;padding:10px;"></pre>    <script>      const out = (x) => (document.getElementById("out").textContent = typeof x === "string" ? x : JSON.stringify(x, null, 2));      let lastB64 = "";      document.getElementById("btnC").onclick = async () => {        const text = document.getElementById("txt").value;        const res = await fetch("http://127.0.0.1:8000/compress", {          method: "POST",          headers: { "Content-Type": "application/json" },          body: JSON.stringify({ text, level: 3 }),        });        const data = await res.json();        lastB64 = data.b64;        out(data);      };      document.getElementById("btnD").onclick = async () => {        if (!lastB64) return out("你先压缩一次,别急。");        const res = await fetch("http://127.0.0.1:8000/decompress", {          method: "POST",          headers: { "Content-Type": "application/json" },          body: JSON.stringify({ b64: lastB64 }),        });        const data = await res.json();        out(data);      };      document.getElementById("btnB").onclick = async () => {        const res = await fetch("http://127.0.0.1:8000/bench?workers=4&iters=25000000");        const data = await res.json();        out(data);      };    </script>  </body></html>

打开这个 HTML,你就能在本地把“压缩/解压/并发测试”全跑一遍。

这就是前端的爽:接口通了,啥端都能接。

鸿蒙 ArkTS 也能调:后端接口通用才是王道

很多人做鸿蒙卡在“网络请求怎么写”。其实鸿蒙的 HTTP 请求模块也挺直接:创建一个 httpRequest,然后 request(url, options) 发出去。给你一段“能看懂、能改”的 ArkTS 示例思路(把 URL 换成你电脑 IP + 端口就行):

import { http } from '@kit.NetworkKit';async function compressOnHarmony(text: string) {  let httpRequest = http.createHttp();  const url = "http://YOUR_PC_IP:8000/compress";  const resp = await httpRequest.request(url, {    method: http.RequestMethod.POST,    header: { 'Content-Type': 'application/json' },    expectDataType: http.HttpDataType.STRING,    extraData: JSON.stringify({ text, level: 3 }),  });  // 返回是字符串就 JSON.parse 一下  const body = JSON.parse(resp.result as string);  return body; // { bytes_in, bytes_out, ratio, b64 }}

鸿蒙这套请求参数(method/extraData/expectDataType/header)就是常用那几个,逻辑跟你写 fetch/axios 的脑回路是一样的:把 body 塞进 extraData,服务端按 JSON 解析就行。

最后唠两句“人话”

你别看我今天吹得热闹,核心就一句:

别老把“学新技术”当成刷题,当成“给自己省事”的买卖。

Python 3.14 这波的意义,不是让你去背 PEP 编号,是真把一些“以前要靠第三方、靠玄学、靠折腾”的东西,慢慢变成官方正经能力:free-threaded 终于被官方认账了(但仍然可选),zstd 也进了标准库,连发布验包的规矩都说清楚了。

你要是做后端,就把接口写稳;

你要是做前端/鸿蒙,就把请求接好;

你要是做性能,就拿 /bench 跑一跑,看看你机器的线程到底能不能真并行。

别的先不管,能把活儿干漂亮,就是硬道理。

#Python #Python314 #多线程 #并发编程 #GIL #后端开发 #FastAPI #接口开发 #前端开发 #Web开发 #鸿蒙开发 #ArkTS #程序员成长 #效率工具 #uv工具 #性能优化