Show HN: Runloom – 适用于Python自由线程的Go风格协程

Hacker News Top 工具

摘要

Runloom是一个新的Python库,为自由线程Python(3.13t/3.14t)提供了Go风格的栈式协程和任务窃取调度器,使得阻塞代码能够在无GIL的情况下跨核心并发运行。它声称在生成吞吐量和调度性能上可以与Go匹敌或超越。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/07/10 15:21

robertsdotpm/runloom

来源:https://github.com/robertsdotpm/runloom

Runloom

面向 Python 的 Go 风格有栈协程。编写 阻塞 代码 — fiber(fn)、普通 recv/send、无需 async/await — 然后在单个进程中跨所有核心运行一百万个协程。手写汇编上下文切换 + C 工作窃取调度器 + 网络轮询,专为 自由线程 Python 3.14t(无 GIL)设计。

import threading, runloom
from urllib.request import urlopen
runloom.monkey.patch()

def crawl(url):
    # urlopen() 看起来是阻塞的——但 monkey.patch() 会将协程挂起在 socket 上而非 OS 线程上,
    # 因此所有 64 次获取在真实核心上重叠执行。
    body = urlopen(url, timeout=10).read()
    print(threading.get_native_id(), len(body))

def main():
    for _ in range(64):
        runloom.fiber(crawl, "http://example.com")

runloom.run(8, main)   # 8 个 hub 线程 -> 3.14t 上的真实核心(无 GIL)

Runloom 对比 Go

相同机器(64 核,自由线程 CPython 3.13t),8 个 hub / GOMAXPROCS=8,预热稳态。Go 在此约为 2.1 M 次创建/秒。

指标runloomGo结论
创建 — 纯 C (c_entry)2.29 M/s2.10 M/s超越 Go
创建 — Python (runloom.fiber)1.35 M/s2.10 M/s0.65×
上下文切换约 75 ns 让出 · 约 560 ns 通道往返约 50 ns Gosched相近
连接/秒 — 抖动(每个请求新建连接)约 75–78 k/s约 75–78 k/s持平
请求/秒 — 保持连接回声,Python 处理596 k/s603 k/s0.99× — 持平(C 处理超越 Go)
内存 — 空挂起协程8.8 KB2.7 KB3.3×(唯一真正的差距)

简要总结:在 创建、调度和吞吐量 上,runloom 与 Go 旗鼓相当,并在纯创建上超越 Go — 一个运行在 CPython 上的有栈协程运行时,即使使用 Python 处理也能匹配编译语言(饱和状态下 596 k 对比 603 k req/s;C 处理超越 Go)。唯一剩下的真正的差距是 内存:挂起的协程携带 CPython 求值帧,约为 Go 每协程 RSS 的 3.3 倍。 完整跨运行时数据及冷启动对比曲线:基准测试报告 (https://github.com/robertsdotpm/runloom/blob/main/benchmark/report.html) · 性能摘要 (https://github.com/robertsdotpm/runloom/blob/main/docs/dev/PERF_SUMMARY.md)。

runloom.optimize("throughput")   # runloom.fiber -> 最大创建速率 (fiber_fast)
runloom.optimize("memory")       # runloom.fiber -> 小尺寸栈(默认)

安装

pip install runloom
import runloom      # 调度器 + 通道,以及 monkey/time/context/sync/aio

为 CPython 3.11–3.14 提供 预编译 wheel(无需编译器),支持 Linux (x86_64/aarch64)、macOS (arm64/x86_64)、Windows (AMD64);其他平台需要从源码构建。无运行时依赖。

它是什么

  • 手写汇编上下文切换(x86_64 SysV, aarch64)— 约 80 ns/次切换,无系统调用;回退到 Windows Fibers / POSIX ucontext
  • M:N 工作窃取调度器(3.13t)— 每个 hub 的 Chase-Lev 双端队列,每个 hub 的 MPSC 提交队列,唤醒的协程路由回其原始 hub。
  • 每协程 PyThreadState 快照 — cframe、数据栈、exc_info、contextvars、递归深度;一百万个让出的协程共享其 hub 线程,无帧链断层。
  • 网络轮询 — epoll / kqueue / IOCP / WSAPoll / select;协程透明地挂起在文件描述符就绪上,无丢失唤醒的三态挂起-提交机制。
  • Go 风格通道Chan(capacity)selectfor v in ch
  • 停滞隔离与恢复 — 一个意外的阻塞调用仅停滞其 hub,运行时检测并恢复(默认开启,3.13t)。
  • monkey.patch() 使阻塞的 stdlib(sockettimethreading、…)变为协作式,因此现有阻塞代码无需修改即可运行。

已有 async def 代码?runloom.aio 桥接在单线程调度器上运行它(runloom.aio.run(main())asyncio.run)— 零重写移植路径,但非多核加速(如需多核,请使用带 run(n>1, main) 的同步 API)。

诚实的局限性

  • 多核优势需要自由线程 CPython 3.13t(帧快照本身需要 3.11+)。在带 GIL 的构建中,runloom 仍可运行 — 廉价创建、协程模型、网络轮询 — 但如同 asyncio 一样单核。
  • runloom 无法提升 Python 每核速度。 CPython 每核约 80k 纯 Python 操作/秒是一个它无法提高的常数;它允许一个进程以阻塞模型同时在每个核心上达到该速度。调度器本身是 Go 级别的。
  • 每个协程内存高于 Go(空纤程约 3.3 倍 — CPython 求值帧;C 处理可以缩小大部分差距)。
  • 抢占仅在 Python 字节码边界触发 — 运行在紧密纯 C 调用(如 numpy)内的协程会持有其 hub 直到返回(与 Go + cgo 相同)。
  • Linux x86_64 / 3.13t 是主要且经过严格验证的目标(200 万连接测试、模糊测试、清理器、形式化模型);其他后端同步维护但深度测试较少。

平台支持

操作系统 / 架构切换网络轮询测试情况
Linux x86_64fcontext-asmepoll是 — 硬件,3.11 / 3.12 / 3.13t / 3.14t(主要)
Linux aarch64fcontext-asmepollqemu
macOS x86_64 / arm64fcontext-asmkqueue硬件,3.14t
FreeBSD / GhostBSDfcontext-asmkqueue硬件,3.12
Windows 10/11 / Server 2022FibersIOCP→WSAPoll→select硬件,3.14t
Solaris / Android / 其他 BSDucontext / asmselect / epoll / kqueue审查

文档与布局

完整指南在 docs/ (https://github.com/robertsdotpm/runloom/tree/main/docs/): 快速入门 (https://github.com/robertsdotpm/runloom/blob/main/docs/quickstart.md) · Asyncio 桥接 (https://github.com/robertsdotpm/runloom/blob/main/docs/asyncio.md) · 同步 API (https://github.com/robertsdotpm/runloom/blob/main/docs/sync-api.md) · 通道 (https://github.com/robertsdotpm/runloom/blob/main/docs/channels.md) · M:N 并行 (https://github.com/robertsdotpm/runloom/blob/main/docs/parallelism.md) · 食谱 (https://github.com/robertsdotpm/runloom/blob/main/docs/cookbook.md) · API 参考 (https://github.com/robertsdotpm/runloom/blob/main/docs/api-reference.md)

目录内容
src/runloom_c/C 扩展:调度器、通道、网络轮询、汇编后端、M:N hubs、停滞恢复
src/runloom/Python 层:aiosyncmonkeytimeruntime
tests/ · examples/ · benchmark/ · docs/测试 · 可运行示例 · 基准测试 + 性能测试工具 · 文档

从源码构建(贡献者):在克隆仓库中执行 pip install -e .(需要 C 编译器;scripts/install.sh / scripts\install.bat 会引导安装一个)。要针对自由线程 CPython 修改 runloom,请使用 3.13t 解释器。

相似文章

自由线程Python:过去、现在与未来

Lobsters Hottest

Thomas Wouters 在 PyCon US 2026 上发表了关于自由线程 Python 的过去、现在与未来的演讲,该 Python 版本移除了全局解释器锁 (GIL),允许并行线程执行。

C语言中的Go风格并发

Hacker News Top

一篇详细的技术文章,探讨如何在C语言中复制Go的并发模型,使用POSIX线程、互斥锁、条件变量和工作池,作为Solod转译器项目的一部分。

Silk: 开源协作式纤程调度器

Hacker News Top

Silk 是一个面向 Linux 的开源协作式纤程调度器,具有每 CPU 调度线程、io_uring 集成和拓扑感知的工作窃取功能,专为低开销下的高并发而设计。