sys.setrecursionlimit仅修改python解释器递归计数器,不扩大底层操作系统分配的c栈空间;linux线程栈约8mb、windows约1mb,超限直接segmentation fault,无recursionerror。

sys.setrecursionlimit 只改计数器,不扩真实栈空间
它只是让 Python 解释器多数几层调用,底层 C 栈(由操作系统分配)没变。Linux 默认线程栈约 8MB,Windows 更小(常 1MB),一旦递归实际占用字节数超限,进程直接 Segmentation fault,连 RecursionError 都不抛——静默崩溃,调试无 traceback。
常见误判:sys.setrecursionlimit(10000) 后跑崩了,以为是“还不够大”,其实是每层压入 2KB 局部变量,5000 层就吃掉 10MB 栈空间,早超 OS 限制。
多线程下全局设限 ≠ 全局安全
sys.setrecursionlimit() 是解释器级全局设置,但每个线程有独立 C 栈。主线程栈大,子线程可能只有默认大小(尤其在 gevent、threading 或 asyncio + threads 混用时),设高限后子线程反而更早崩。
- 子线程栈不可控,
threading.stack_size()仅对新线程生效,且 Windows 不支持 - 第三方库(如
concurrent.futures)创建的线程不会继承你调大的 limit - PyPy、Jython 等解释器完全忽略该设置,代码一移植就失效
它掩盖算法缺陷,而非修复问题
报 RecursionError: maximum recursion depth exceeded 很可能说明:base case 漏写、参数未收敛(比如 factorial(n) 调自己而非 factorial(n-1))、__repr__ 打印时隐式递归、mock 对象循环引用——这些根本不是“深度不够”,而是逻辑错误。
典型陷阱:
- pytest 输出失败信息时反复调
obj.__repr__(),触发链式递归 - 装饰器嵌套过深(如多个
@lru_cache+@wraps),叠加调用帧 - 解析用户提交的 JSON/XML,深度完全不可控,设成 2000 挡不住 3000 层恶意输入
真正该优先做的三件事
遇到 RecursionError,先别碰 sys.setrecursionlimit():
- 用
traceback.print_stack(limit=5)看最后几帧是否重复同一函数名,确认是不是真递归 - 检查是否能转迭代:DFS、树遍历、阶乘、快排——全都可以用
list或deque模拟栈 - 评估数据结构合理性:嵌套超 100 层的 JSON,大概率该换
json.JSONDecoder().raw_decode流式解析,而不是硬递归
真正需要调限的场景极少:仅当递归逻辑干净、深度可预估(如固定 1800 层语法树)、运行环境单线程且栈充足,并且已实测每层开销、留足余量——否则,调限就是在给定时炸弹调表盘。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











